BeanFactoryPostProcessor
BeanFactoryPostProcessor
BeanFactoryPostProcessor功能
BeanFactoryPostProcessor 是BeanFactory的后置处理器,在BeanFactory标准初始化之后调用.
下面测试BeanFactoryPostProcessor 功能
-
我们定义类实现BeanFactoryPostProcessor接口
-
配置类
@ComponentScan("com.atguigu.ext")//扫描我们自定义的BeanFactoryPostProcessor到容器中 @Configuration public class ExtConfig { @Bean public Blue blue(){ return new Blue(); } }
-
测试类
public class IOCTest_Ext { @Test public void test01(){ //1. 创建ioc容器 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); applicationContext.close(); }
时机
BeanFactory标准初始化之后: 所有bean definition已经加载到beanFactory,但是实例未创建的时候
BeanFactoryPostProcessor 实现原理
ioc容器创建
其中,refresh() 如下:
在invokeBeanFactoryPostProcessors 我们的beanFactoryPostProcessors会被调用
invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors 方法:
然后调的invokeBeanFactoryPostProcessors 方法如下:
-
从beanFactory 找到所有BeanFactoryPostProcessor类型 把名字存下来
-
将获得的BeanFactoryPostProcessor分类
按实现了PriorityOdered Ordered 和NonOrdered顺序 分好类
这里的processedBeans.contains(ppName)就是前面已经执行过的,因为上面是BeanDefinitionRegistryPostProcessor的执行, 因为BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,所以beanFactory也会拿到这个类型的,要把这些执行过的都排除掉
invokeBeanFactoryPostProcessors
- 执行每一个BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);//因为我们当前的BeanFactoryPostProcessor是nonOrderedPostProcessors,所以调的是这里
ConfigurableListableBeanFactory:
遍历所有这个集合的BeanFactoryPostProcessor,调用其postProcessBeanFactory方法
BeanDefinitionRegistryPostProcessor
先通过BeanDefinitionRegistryPostProcessor注册BeanDefinition,再执行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
在默认情况下,只有一个BeanDefinitionRegistryPostProcessor会执行,就是ConfigurationClassPostProcessor,因为它是Spring默认在添加进去的
功能
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口
它有自己的方法
功能测试:
测试结果:
执行时机
执行时机:
所有bean定义信息将要被加载,bean实例还未创建
我们可以用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件
原理
BeanDefinitionRegistryPostProcessor 调自己方法的部分 和 BeanFactoryPostProcessor 调自己方法的部分是在一个函数里的,所以前面过程都一样的,
只不过invokeBeanFactoryPostProcessors函数中 前半部分是处理BeanDefinitionRegistryPostProcessor调自己方法,而后部分是BeanFactoryPostProcessor 的.
ioc容器创建
其中,refresh() 如下:
在invokeBeanFactoryPostProcessors 中BeanDefinitionRegistryPostProcessor的方法会被调用
invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors方法:
invokeBeanDefinitionRegistryPostProcessors
- 按优先级,每次都从beanFactory中找到所有类型为BeanDefinitionRegistryPostProcessor类型的
每个优先级都要重新从beanFactory获取,因为每次执行一个BeanDefinitionRegistryPostProcessors就可能会加载新的BeanDefinition
currentRegistryProcessors = new ArrayList();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
- 对每个优先级的postProcessor,执行invokeBeanDefinitionRegistryPostProcessors ,依次调用所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
- 调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
详细的过程如下:
// 1. 如果beanFactory实现了BeanDefinitionRegistry接口,则表示可以通过BeanDefinitionRegistryPostProcessor接口来注册BeanDefinition
// 2. 因为现在是Spring启动过程中的比较早的阶段(还没有开始扫描@Component),所以只能获取Spring默认添加到BeanFactory中的bean工厂后置处理器,以及程序员手动添加的bean工厂后置处理器
// 3. 执行的顺序是,先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法,因为这个方法可以注册BeanDefinition
// 4. 先执行手动添加进行来的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,这个过程中可能会向BeanFactory中注册其他的BeanDefinitionRegistryPostProcessor
// 5. 从BeanFactory中获取PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
// 6. 从BeanFactory中获取Ordered接口的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
// 7. 在5,6步中都有可能注册新的BeanDefinitionRegistryPostProcessor的
// 8. 从BeanFactory中获取普通的BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法
// 9. 在8步中也有可能注册新的BeanDefinitionRegistryPostProcessor,所以第8步会递归,直到没有新的BeanDefinitionRegistryPostProcessor注册进来了
// 10. 在前面的步骤中都是执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法,进行BeanDefinition的注册
// 11. BeanDefinition注册完了之后,因为BeanDefinitionRegistryPostProcessor本身也是一个BeanFactoryProcessor,所以最后再执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors
再下面就是用invokeBeanFactoryPostProcessors 调用BeanFactoryPostProcessors类型的部分了
原理总结
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口, 真正执行的时候是在一个函数中前后调用的
都是refresh() ->invokeBeanFactoryPostProcessors->invokeBeanFactoryPostProcessors 中