BeanFactoryPostProcessor和BeanPostProcessor

BeanFactoryPostProcessor和BeanPostProcessor,这两个接口,都是Spring初始化bean时对外暴露的扩展点。两个接口名称看起来很相似,但作用及使用场景却不同,分析如下:

1、BeanFactoryPostProcessor接口

该接口的定义如下:

public interface BeanFactoryPostProcessor {

/**
 * Modify the application context's internal bean factory after its standard
 * initialization. All bean definitions will have been loaded, but no beans
 * will have been instantiated yet. This allows for overriding or adding
 * properties even to eager-initializing beans.
 * @param beanFactory the bean factory used by the application context
 * @throws org.springframework.beans.BeansException in case of errors
 */
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

} 实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。

注意:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息。

2、BeanPostProcessor接口

该接口的定义如下:

public interface BeanPostProcessor {

} BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:

1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet

2)在bean定义的时候,通过init-method设置的方法

注意:BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的。BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。

3、实战

BeanFactoryPostProcessor

BeanPostProcessor

配置类

Bean

启动类

执行顺序:

BeanFactoryPostProcessor对Bean属性的修改延迟到了Bean初始化完成之后才执行

4、进一步深入分析

在使用ApplicationContext启动spring容器的时候,在AbstractApplicationContext.refresh()方法中,完成相关初始化工作:

img

1)BeanFactoryPostProcessor.postProcessBeanFactory,是在第5步执行的

2)而BeanPostProcessor的执行,取决于配置文件中bean的定义,如果定义的bean是singleton并且不是抽象类,也不延迟初始化,则BeanPostProcessor是在第11步中执行;而对于prototype的bean,BeanPostProcessor是在程序getBean的时候执行的。在第6步中,调用registerBeanPostProcessors方法,注册所有实现BeanPostProcessor接口的bean

5、总结

1、创建(调用构造函数) 2、set属性(set方法注入属性) 3、判断是否实现BeanNameAware接口,并调用接口的setBeanName方法 4、判断是否实现BeanFactoryAware接口,并调用接口的setBeanFactory方法 5、判断是否实现ApplicationContextAware接口,并调用接口的setApplicationContext方法 6、判断是否实现BeanPostProcessor接口,并调用接口的postProcessBeforeInitialization方法 7、判断是否实现InitializingBean接口,并调用接口的afterPropertiesSet方法 8、判断是否自定义init方法,并调用 9、判断是否实现BeanPostProcessor接口(同6),并调用接口的postProcessAfterInitialization方法 10、业务代码中Bean对象的使用 11、当容器销毁时,判断是否实现DisposableBean接口,并调用接口的destroy方法 12、判断是否自定义销毁方法,并调用

对于 BeanNameAware BeanFactoryAware ApplicationContextAware 这3个接口我们平时很少实现它,一般用于让Bean能够感知到BeanName BeanFactory ApplicationContext

参考

Spring的BeanFactoryPostProcessor和BeanPostProcessor

最后更新于

这有帮助吗?