一、概述
通过上一篇spring bean扩展点:后处理器 BeanPostProcessor,我们知道 BeanPostProcessor
是用来改变bean实例的。同样在 Spring 容器启动阶段,Spring 也提供了一种容器扩展机制:BeanFactoryPostProcessor
,该机制作用于容器启动阶段,允许我们在容器实例化 Bean 之前对注册到该容器的 BeanDefinition
做出修改。
BeanFactoryPostProcessor 为spring在容器初始化时对外对外暴露的扩展点,Spring IoC容器允许BeanFactoryPostProcessor在容器加载注册BeanDefinition完成之后读取BeanDefinition(配置元数据),并可以修改它。如果业务需要,可以配置多个BeanFactoryPostProcessor的实现类,通过”order”控制执行次序(要实现Ordered接口)。
PS : 个人感觉,实现IOC的两个核心后处理器 :
ConfigurationClassPostProcessor
解析配置类(这里的配置类不仅仅局限于@Configuration 注解,还包括 @Import、 @ImportResource 等注解),将解析到的需要注入到Spring容器中的bean的BeanDefinition保存起来AutowiredAnnotationBeanPostProcessor
解析bean中的 需要自动注入的bean @Autowired 和 @Inject @Value注解。
其中 ConfigurationClassPostProcessor
就是BeanFactory 后置处理器实现类
1.1、三重要的 BeanFactory扩展点
- 1、ImportBeanDefinitionRegistrar的registerBeanDefinitions() 方法
- 2、BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
- 3、BeanFactoryPostProcessor 的postProcessBeanFactory方法
由于AnnotationConfigApplicationContext#refresh()容器生命周期中invokeBeanFactoryPostProcessors
方法中主要就是对BeanFactoryPostProcessor
的处理,所以这里简单的介绍一下 BeanFactoryPostProcessor
及其子接口 BeanDefinitionRegistryPostProcessor
。其结构如下图:
BeanFactoryPostProcessor
相比较于 BeanPostProcessor
方法是很简单的,只有一个方法,其子接口也就一个方法。但是他们俩的功能又是类似的,区别就是作用域并不相同。BeanFactoryPostProcessor
的作用域范围是容器级别的。它只和你使用的容器有关。如果你在容器中定义一个BeanFactoryPostProcessor
,它仅仅对此容器中的bean进行后置处理。BeanFactoryPostProcessor
不会对定义在另一个容器中的bean进行后置处理,即使这两个容器都在同一容器中。BeanFactoryPostProcessor
可以对 bean的定义(配置元数据)进行处理。Spring IOC 容器允许 BeanFactoryPostProcessor
在容器实际实例化任何其他bean之前读取配置元数据,并有可能修改它,也即是说 BeanFactoryPostProcessor 是直接修改了bean的定义,BeanPostProcessor 则是对bean创建过程中进行干涉。
BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 的区别在于:
-
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
方法针对是BeanDefinitionRegistry
类型的ConfigurableListableBeanFactory
,可以实现对BeanDefinition
的增删改查等操作,但是对于非 ConfigurableListableBeanFactory 类型的BeanFactory,并不起作用。 -
BeanFactoryPostProcessor#postProcessBeanFactory
针对的是所有的BeanFactory
。 -
postProcessBeanDefinitionRegistry
的调用时机在postProcessBeanFactory
之前。
1.2 、代码示例:
/**
* 和BeanPostProcessor原理一致,Spring提供了对BeanFactory进行操作的处理器BeanFactoryProcessor,简单来说就是获取容器BeanFactory,这样就可以在真正初始化bean之前对bean做一些处理操作。
* 允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行