美文网首页
吃透Spring的BeanFactoryPostProcesso

吃透Spring的BeanFactoryPostProcesso

作者: rock_fish | 来源:发表于2019-12-06 10:46 被阅读0次

    传送:

    Spring大观园,我有过的困惑或许你也有!

    springboot 注解处理流程 笔记中大致解释过BeanFactoryPostProcessor,还提到处理注解的核心类ConfigurationClassPostProcessor在AnnotatedBeanDefinitionReader构造函数中注册到容器,在invokeBeanFactoryPostProcessors方法中被调用。
    开始下文源码阅读之前,最好先查看springboot 注解处理流程BeanFactoryPostProcessor的作用,对其有更全面的认识,帮助理解源码。

    留意核心类ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry调用 在源码注释中,查看第二波

    这里开始梳理了下invokeBeanFactoryPostProcessors方法的源码。

    springboot项目中invokeBeanFactoryPostProcessors方法执行时传入的参数为

    0 = {SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor@3818} 
    1 = {ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor@3819} 
    2 = {ConfigFileApplicationListener$PropertySourceOrderingPostProcessor@3820}
    
    /**
     *  BeanFactoryPostProcessor 是对BeanFactory的补充处理.往容器中添加bean定义
     *  postProcessBeanDefinitionRegistry 实现 BeanFactoryPostProcessor 从名字上看,更明确 往容器中添加bean定义 的功能.
     *  有几个优先处理逻辑:
     *      1. postProcessBeanDefinitionRegistry 优先于 BeanFactoryPostProcessor
     *      2. PriorityOrdered 优先于 Ordered
     *
     *  上下文中已有的beanFactoryPostProcessors作为参数传入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法
     *  此时还没有执行扫描,所以context的BFPP列表中的都是通过api `ConfigurableApplicationContext#addBeanFactoryPostProcessor`添加的.
     *  如果是BeanDefinitionRegistryPostProcessor类型,将执行其方法`postProcessBeanDefinitionRegistry`,往容器中注册bean定义.
     *
     */
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    
        //已实例化的Bean集合
        Set<String> processedBeans = new HashSet<>();
    
        /********第一波 postProcessBeanDefinitionRegistry 调用
              // 这一波 被调用的接口是 通过接口调用,添加到context 的变量 List<BeanFactoryPostProcessor>中的
              // BeanDefinitionRegistryPostProcessor
        ****************************************************************************************/
    
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 存放所有BeanFactoryPostProcessor,不包括BeanDefinitionRegistryPostProcessor类型
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            // 存放所有 BeanDefinitionRegistryPostProcessor类型的
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
    
                    // 第一波 postProcessBeanDefinitionRegistry 调用
                    // 这一波 是 通过接口调用,添加到context 的变量 List<BeanFactoryPostProcessor>中的
                    // BeanDefinitionRegistryPostProcessor
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    //存一下
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }
    
            // 不能初始化 FactoryBeans,他们需要 被 factory 的 post-processors 处理。
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
    
            //临时容器,放置一些内容,排序后,归档到  registryProcessors 中后,就重置清理了.
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
        /********第二波 postProcessBeanDefinitionRegistry 调用          */
              // 这一波 是 beanFactory 实现了PriorityOrdered接口 BeanDefinitionRegistryPostProcessor 类型的的
    //核心类ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry在此处被调用
        /****************************************************************************************/
    
    
            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 2.beanFactory 的bean定义中筛选出 BeanDefinitionRegistryPostProcessor 类型的,
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
            for (String ppName : postProcessorNames) {
                // beanFactory 的bean定义中筛选出 BeanDefinitionRegistryPostProcessor 类型的,并且还实现了PriorityOrdered接口的,实例化,放到currentRegistryProcessors中.
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    //getBean实例化后,放置到 currentRegistryProcessors
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 已实例化的bean名称放到processedBeans中.
                    processedBeans.add(ppName);
                }
            }
    
            //排序 此时 currentRegistryProcessors 中的都实现了PriorityOrdered接口,按照value值排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 把 currentRegistryProcessors 添加到(尾部追加) registryProcessors.
            registryProcessors.addAll(currentRegistryProcessors);
            // 第二波 postProcessBeanDefinitionRegistry 调用,这一波是springFactory中拿到的 BeanDefinitionRegistryPostProcessors
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            // currentRegistryProcessors 这个临时容器元素清空
            currentRegistryProcessors.clear();
    
    
            /********第三波 postProcessBeanDefinitionRegistry 调用
                      // 这一波 是 beanFactory 实现了 Ordered 接口 的 BeanDefinitionRegistryPostProcessor 类型的
                      // 思考:
                      // 因为PriorityOrdered接口 继承了 Ordered 接口,按照 Ordered 来筛选,能取出  实现接口PriorityOrdered的 和 实现了接口Ordered的
                      // 第二波里新注册的 BeanDefinitionRegistryPostProcessor 类型bean定义中 可能是实现了 PriorityOrdered接口 也可能是实现了 Ordered 接口
                      // 所以第三波从 beanFactory 取出的是所有的 实现接口PriorityOrdered的 或者 实现了接口Ordered的BeanDefinitionRegistryPostProcessor
                      // 没有实例化的(processedBeans中不存在),getBean实例化后添加到currentRegistryProcessors中,也添加到processedBeans中(标记为已实例化);
                      // 通过sortPostProcessors 排序,PriorityOrdered 优先级高于 Ordered
                      // 执行 postProcessBeanDefinitionRegistry 调用,往容器中注册bean定义
                      // 清空临时容器
            ****************************************************************************************/
    
            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            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();
    
    
            /********第四波 postProcessBeanDefinitionRegistry 调用 直到容器中所有的 BeanDefinitionRegistryPostProcessor 都被处理过。即么有新的注册进来。
                  // 这一波是循环式操作
                  // 1. 从 beanFactory 中取出未实例化的 BeanDefinitionRegistryPostProcessor 放置到 currentRegistryProcessors中,
                  // 2. 如果取到了未实例化的 通过 sortPostProcessors 对 currentRegistryProcessors中排序后, 顺序调用其 postProcessBeanDefinitionRegistry方法,往容器中注册bean定义,清空临时容器继续1
                  // 3. 如果未取到 未实例化的,则退出循环.
            ****************************************************************************************/
    
            // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
            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();
            }
    
            // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            /********第一波 postProcessBeanFactory 调用
                  // 1. 遍历registryProcessors 中元素BeanDefinitionRegistryPostProcessor  调用其 postProcessBeanFactory方法
                  // 2. 遍历regularPostProcessors 中元素BeanFactoryPostProcessor 调用其 postProcessBeanFactory方法,
                  // 此时regularPostProcessors中的是appContext的属性里筛选出的BeanFactoryPostProcessor,设计者认为这种通过编程方式直接加入的执行的优先级都比较高
                  // 这两拨调用也可能会往容器里注册 BeanFactoryPostProcessor
            ****************************************************************************************/
    
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }
    
        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }
    
        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
    
        /********第二波 postProcessBeanFactory 调用
                      // 从 容器中取 BeanFactoryPostProcessor类型的
                      // 忽略已经被调用过的
                      // 筛选出 实现 PriorityOrdered  实例化放入 priorityOrderedPostProcessors
                      // 剩下的筛选出 实现 Ordered  不实例化,只把名字 放入 orderedPostProcessorNames
                      // 最后剩下的 不实例化,只把名字 放入 nonOrderedPostProcessorNames
    
                ****************************************************************************************/
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {
            if (processedBeans.contains(ppName)) {
                // skip - already processed in first phase above
            }
            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);
            }
        }
    
        // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
        // 先处理PriorityOrdered 优先级的 priorityOrderedPostProcessors
        // 对priorityOrderedPostProcessors排序后,遍历调用其BeanFactoryPostProcessor方法
    
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 其次 处理 Ordered 优先级的 ,
        // 遍历orderedPostProcessorNames,实例化后,放入 orderedPostProcessors 排序,
        // 对orderedPostProcessors排序后,遍历调用其BeanFactoryPostProcessor方法
    
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    
        // Finally, invoke all other BeanFactoryPostProcessors.
        // 最后 处理 剩下的,
        // 遍历 nonOrderedPostProcessorNames,实例化后,放入 nonOrderedPostProcessors 排序,
        // 对 nonOrderedPostProcessors 排序后,遍历调用其BeanFactoryPostProcessor方法
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
        // Clear cached merged bean definitions since the post-processors might have
        // modified the original metadata, e.g. replacing placeholders in values...
    
        // 清空元数据缓存
        beanFactory.clearMetadataCache();
    }
    
    

    相关文章

      网友评论

          本文标题:吃透Spring的BeanFactoryPostProcesso

          本文链接:https://www.haomeiwen.com/subject/esvsgctx.html