【Spring注解】BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor

BeanFactoryPostProcessor功能

BeanFactoryPostProcessor 是BeanFactory的后置处理器,在BeanFactory标准初始化之后调用.

下面测试BeanFactoryPostProcessor 功能

  1. 我们定义类实现BeanFactoryPostProcessor接口
    在这里插入图片描述

  2. 配置类

    @ComponentScan("com.atguigu.ext")//扫描我们自定义的BeanFactoryPostProcessor到容器中
    @Configuration
    public class ExtConfig {
        @Bean
        public Blue blue(){
            return new Blue();
        }
    }
    
  3. 测试类

    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 中

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值