所属知识点 IOC加载和Bean的生命周期
@PostConstruct失效 情况1:BeanFactoryPostProcessor
一次偶然发现,@PostConstruct
不生效,反复尝试发现应该是BeanFactoryPostProcessor
作祟,只要实现此接口,注解就不生效。
最后没有得出一个具体的答案,但是尝试分析了一下,应该可以证明是
BeanFactoryPostProcessor
的问题,具体以后看了源码再补充吧
@Component
public class A implements BeanFactoryPostProcessor {
@PostConstruct
public void piodwa(){
System.out.println("PostConstruct A");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
猜测
根据我对Bean初始化的了解,BeanFactoryPostProcessor
的执行时机是在所有BeanDefinition注册后,这个时候Bean根本还未被初始化!
而@PostConstruct
属于初始化的一部分,等到初始化的时候,发现 A的对象 已经存在 ,所以就不初始化了。这个不知道是不是spring的一个bug。
验证代码
在配置类中加入init初始化方法来对照
@Bean(initMethod = "init")
public A a(){
return new A();
}
测试的Bean为以下的class A,在没有implements BeanFactoryPostProcessor
(理想)情况下,输出结果应该为:
B…
A…
PostConstruct A
b:com.cying.digital.B@xxxxxx
initA
但是,implements BeanFactoryPostProcessor
后:
A…
b:null
initA
BeanFactoryPostProcessor…
B…
so,想在所有BeanDefinition注册完后在BeanFactoryPostProcessor->postProcessBeanFactory()
里面干事情,还是单独一个Bean用的好。
@Component
public class B {
public B(){
System.out.println("B...");
}
}
//测试用的Bean A
public class A implements BeanFactoryPostProcessor{
@Autowired
private B b;
public A(){
System.out.println("A...");
}
@PostConstruct
public void postConstructA(){
System.out.println("PostConstruct A");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("BeanFactoryPostProcessor...");
}
public void init(){
System.out.println("b:"+b);
System.out.println("initA");
}
}
@PostConstruct失效 情况2:BeanFactory注册bean
通过ConfigurableListableBeanFactory 注入的bean,PostConstruct也会失效
这里可以查看autowireBean和registerSingleton两个方法的官方注释,autowireBean只是帮你注入需要的依赖,registerSingleton只是注册bean到IOC
@Autowired
private ConfigurableListableBeanFactory beanFactory;
beanFactory.autowireBean(job);
beanFactory.registerSingleton(task.getId(), job);