两个类,BeanA 和 BeanB ,其中 BeanA 中引用了BeanB,那么 @PostContrust
的触发时机是什么时候呢。 其实顾名思义,Post 是后的意思,Contrust是建造的意思,可以猜想是在构造函数完成之后,下面用代码做实验
类 BeanA
@Component
public class BeanA {
@Autowired
private BeanB beanB;
public BeanA(){
System.out.println("这是 BeanA 的构造函数");
}
@PostConstruct
private void init() {
System.out.println("这是BeanA 的 init 方法");
beanB.testB(); // 调用测试函数
}
}
类 BeanB
@Component
public class BeanB {
@PostConstruct
private void init() {
System.out.println("这是BeanB 的init 方法");
}
public BeanB() {
System.out.println("这是Bean B的 构造方法");
}
void testB() {
System.out.println("这是Bean B 的 test 方法");
}
}
测试类:
public class FirstTest {
public static void main(String[] args) {
// 用我们的配置文件来启动一个 ApplicationContext
ApplicationContext context =
new ClassPathXmlApplicationContext("classpath:application.xml");
}
}
结果:
其实在 BeanA 进行 类加载之后, beanB的引用还是 null,然后进行 自身的构造函数,之后就要把 beanB 的属性注入进去了。结果发现 BeanB 还没有 实例化,要有实例就先类加载,加载完之后调用BeanB 的构造函数就是实例化了。
注意,一旦调用完构造函数之后,这个类的实例就在内存中真实存在了,即使刚才没有实例化的时候 beanB属性 是空的,但它是个引用。所以现在引用指向的就不是空的了,这个思想就是Spring解决循环依赖的方法。
由此可见,他们的顺序是:
@Construct
--> @AutoWired
--> @PostContrust