BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

invokeBeanFactoryPostProcessors 执行过程分析

invokeBeanFactoryPostProcessors 这个方法实现非常长,但是基本处理过程很简单,存在很多重复的步骤。为了方便理解整个过程,这里还是有必要贴一下代码,代码中会详细标注所做的事情是什么,这个过程是构建 BeanFactory 非常重要一步。掌握这个过程,就可以随意玩转 BeanFactoryPostProcessor 了。

 // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();
    // 当前 beanFactory 是否是 BeanDefinitionRegistry 类型
    // 只有是 BeanDefinitionRegistry 类型,才具备注册 beanDefinition 的能力
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        // 普通的 BeanFactoryPostProcessor 集合
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        // BeanDefinitionRegistryPostProcessor 类型处理器集合
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        // 这里 beanFactoryPostProcessors 是在 SharedMetadataReaderFactoryContextInitializer 中加进来的,是 Spring 自己的处理器
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 如果是 BeanDefinitionRegistryPostProcessor 类型,就加到 registryProcessors
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 执行 BeanDefinitionRegistryPostProcessor 后置处理
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                // 否则就放到 regularPostProcessors
                regularPostProcessors.add(postProcessor);
            }
        }

        // 不要在这里初始化 FactoryBeans:需要保留所有未初始化的常规bean,以使 beanFacotryPostProcessor 对其处理!
        // 分离实现 PriorityOrdered,Ordered和其余优先级的 BeanDefinitionRegistryPostProcessor。
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // 首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors。
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 遍历 BeanDefinitionRegistryPostProcessors
        for (String ppName : postProcessorNames) {
            // 只处理实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 符合上述条件的 BeanDefinitionRegistryPostProcessor 放到 currentRegistryProcessors 中,供后面使用
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 标记当前 postProcessor 已经处理过了
                processedBeans.add(ppName);
            }
        }
        // 排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 调用 BeanDefinitionRegistryPostProcessor 后置处理器
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // 接下来,调用实现 Ordered的BeanDefinitionRegistryPostProcessors
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // 最后,调用所有其他 BeanDefinitionRegistryPostProcessor,直到不再出现(保证全部处理完)。
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }

        // 现在,调用到目前为止已处理的所有处理器的 postProcessBeanFactory 回调。
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // 调用在上下文实例中注册的工厂处理器。就是前面提到的 SharedMetadataReaderFactoryContextInitializer 中注册的
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 这里再次拿到所有的 BeanFactoryPostProcessor
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // 同样将实现 PriorityOrdered、Order 和普通的 BeanFactoryPostProcessor 分离开
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // 跳过-已在上述第一阶段处理过
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 首先,调用实现PriorityOrdered的BeanFactoryPostProcessors。
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 优先执行实现 PriorityOrdered 接口的 BeanFactoryPostProcessor
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 接下来,调用实现Ordered的BeanFactoryPostProcessors。
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 执行实现 Ordered 接口的 BeanFactoryPostProcessor
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // 最后,调用所有其他 BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 执行其他没有实现任何优先级接口的 BeanFactoryPostProcessor
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    // 清除缓存的合并 beanDefinition,因为后处理器可能已经修改了原始元数据
    beanFactory.clearMetadataCache();
}

上面代码段中大体就是,先处理 BeanDefinitionRegistryPostProcessor 类型的 BeanFactoryPostProcessor ,然后再处理普通的 BeanFactoryPostProcessor;在这里处理过程中,会根据一些排序规则来调整各个 BeanFactoryPostProcessor 的执行顺序。

这里先处理 BeanDefinitionRegistryPostProcessor 类型的 BeanFactoryPostProcessor 是一定的,因为需要在这个阶段去注册 BeanDefinition。在 classpath 下的所有 BeanDefinition 都被注册之后,再执行普通 BeanFactoryPostProcessor 的后置回调,这样就可以覆盖所有的 BeanDefinition。

invokeBeanDefinitionRegistryPostProcessors 执行过程分析

在第一次调用 invokeBeanDefinitionRegistryPostProcessors 时,当前的 BeanDefinitionRegistryPostProcessor 只有一个,就是 org.springframework.context.annotation.ConfigurationClassPostProcessor 。

在 ConfigurationClassPostProcessor 类中,会解析 @Configuration、@ComponentScan、@ComponentScans、@Import 等注解。ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 接口,而 BeanDefinitionRegistryPostProcessor 接口继承了 BeanFactoryPostProcessor 接口,所以 ConfigurationClassPostProcessor 中需要重写 postProcessBeanDefinitionRegistry() 方法和 postProcessBeanFactory() 方法。而 ConfigurationClassPostProcessor 类的作用就是通过这两个方法去实现的。更多细节可以参考 ConfigurationClassPostProcessor源码解析 这篇文章,写的非常 nice。

invokeBeanDefinitionRegistryPostProcessors 处理的核心过程如下:

  • 1、ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry:BeanDefinition 触发加载的入口
  • 2、ConfigurationClassPostProcessor#processConfigBeanDefinitions:解析配置类,在此处会解析配置类上的注解(ComponentScan扫描出的类,@Import注册的类,以及@Bean方法定义的类)
  • 3、ComponentScanAnnotationParser#parse:根据注解的属性值来过滤加载 classpath 下的 beanDefinition(默认条件就是 basePackages,默认的 basePackages 为当前启动类的根包)
  • 4、ClassPathBeanDefinitionScanner#doScan:处理 basePackages 下所以的 beanDefinition,被打了 @Service、@Compoment 等注解的类都会被解析到
  • 5、DefaultListableBeanFactory#registerBeanDefinition:将 beanDefinition 注册到 BeanFactory 中(beanDefinitionMap 中)

BeanFactoryPostProcessor 对 BeanDefinition 的修改

实现了一个 BeanFactoryPostProcessor ,没有实现任何排序接口。这个 TestBeanServiceBeanFactoryPostProcessor 的作用是将原来的 TestBeanService 修改为 ProxyTestBeanService。代码如下:

public class TestBeanServiceBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 根据类型拿到所有的 beanNames
        Iterable<String> beanNames = getBeanNames(beanFactory, TestBeanService.class);
        // 这里因为只有一个 TestBeanService ,所以只处理第一个
        beanNames.forEach(beanName -> {
            System.out.println("begin to execute BeanFactoryPostProcessor...");
            BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
            // 先从工程中拿到原始 beanDefinition
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
            // 这里构建一个新的 BeanDefinition,类型为 ProxyTestBeanService,ProxyTestBeanService 是 TestBeanService 的子类
            RootBeanDefinition proxy = new RootBeanDefinition(ProxyTestBeanService.class);
            // 这里设置指定的initMethod
            proxy.setInitMethodName(beanDefinition.getInitMethodName());
            // 设置一些属性
            proxy.setPropertyValues(beanDefinition.getPropertyValues());
            proxy.setPrimary(beanDefinition.isPrimary());
            proxy.setRole(BeanDefinition.ROLE_APPLICATION);
            // 将原始 beanDefinition 移除掉
            beanDefinitionRegistry.removeBeanDefinition(beanName);
            // 将代理的新的 beanDefinition 注册进去
            beanDefinitionRegistry.registerBeanDefinition(beanName,proxy);
            System.out.println("current bean type is : " + proxy.getBeanClass().getTypeName());
            return;
        });
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值