@PostConstruct 失效之(Bean实现了BeanFactoryPostProcessor)

文章目录

  • @PostConstruct失效 情况1:BeanFactoryPostProcessor
    • 猜测
    • 验证代码
  • @PostConstruct失效 情况2:BeanFactory注册bean

所属知识点 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。
@PostConstruct 失效之(Bean实现了BeanFactoryPostProcessor)_第1张图片

验证代码

在配置类中加入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);

你可能感兴趣的:(Java知识,java,面试)