zoukankan      html  css  js  c++  java
  • spring之BeanFactoryPostProcessor执行流程

    转载自:https://www.jianshu.com/p/5323114c0d05

    描述

    BeanFactoryPostProcessor 为spring在容器初始化时对外对外暴露的扩展点,Spring IoC容器允许BeanFactoryPostProcessor在容器加载注册BeanDefinition完成之后读取BeanDefinition(配置元数据),并可以修改它。

    下面跟踪spring源码阅读BeanFactoryPostProcessor的加载机制以及执行时机

    执行入口

    // AbstractApplicationContext 类
     @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                //容器刷新前的处理方法
                prepareRefresh();
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
                //使用容器前beanFactory的前置处理方法
                prepareBeanFactory(beanFactory);
    
                try {
                    postProcessBeanFactory(beanFactory);
    
                    //在容器中执行bean工厂后置处理器
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
                    initMessageSource();
                    initApplicationEventMulticaster();
                    onRefresh();
                    registerListeners();
                    finishBeanFactoryInitialization(beanFactory);
                    finishRefresh();
                }
                catch (BeansException ex) {
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
                    // Reset 'active' flag.
                    cancelRefresh(ex);
                    // Propagate exception to caller.
                    throw ex;
                }
                finally {
                    resetCommonCaches();
                }
            }
        }
    

    spring IOC容器ApplicationContext 在完成包扫描,xml配置加载(BeanDefinition注册后)都会调用refresh方法完成容器的刷新工作即容器的启动工作。

    在refresh方法中有如下一行:

    //执行容器工厂的后置处理器,
    invokeBeanFactoryPostProcessors(beanFactory);
    

    此行就是spring执行容器后置处理器的入口方法,下面接着跟踪invokeBeanFactoryPostProcessors方法:

        /**
         * 实例化并调用所有已注册的BeanFactoryPostProcessor bean,如果给定,则遵守显式顺序。
         */
        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            //通过PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法执行BeanFactoryPostProcessor
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
        }
    

    invokeBeanFactoryPostProcessors 方法很简单,通过PostProcessorRegistrationDelegate类的静态方法invokeBeanFactoryPostProcessors执行后置处理器。此方法完成两件事:

    1. 调用getBeanFactoryPostProcessors()方法获取手工注册到ApplicationContext的容器后置处理器集合
    2. 调用静态方法invokeBeanFactoryPostProcessors并传入后置处理器集合批量执行后置处理器

    后置处理器执行

    在上面看到了spring是通过静态方法invokeBeanFactoryPostProcessors执行后置处理,下面跟踪invokeBeanFactoryPostProcessors方法:

    // 类PostProcessorRegistrationDelegate
    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            //保存所有后置处理器bean名称的集合
            Set<String> processedBeans = new HashSet<>();
    
            //判断beanFactory 是否是BeanDefinitionRegistry
            // 当是BeanDefinitionRegistry 时
            // 将beanFactoryPostProcessors 分为BeanFactoryPostProcessor集合与BeanDefinitionRegistryPostProcessor集合
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                //BeanFactoryPostProcessor集合
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                //BeanDefinitionRegistryPostProcessor集合
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    //遍历查询BeanFactoryPostProcessor是否为BeanDefinitionRegistryPostProcessor
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        //当前postProcessor为BeanDefinitionRegistryPostProcessor是执行postProcessBeanDefinitionRegistry方法
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                // 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.
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
                // 首先在容器中查找实现了PriorityOrdered接口的的BeanDefinitionRegistryPostProcessors(bean定义注册后置处理器)名称
                // 将查找到的名称集合放置到processedBeans中,以及将后置处理器添加到集合currentRegistryProcessors中
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
    
                //对currentRegistryProcessors集合排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                //将当前查找到的currentRegistryProcessors放置到注册后置处理器集合中
                registryProcessors.addAll(currentRegistryProcessors);
                //遍历循环执行currentRegistryProcessors集合中的bean定义注册后置处理器
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                //清空currentRegistryProcessors集合
                currentRegistryProcessors.clear();
    
                // 下来在容器中查找实现了Ordered接口的的BeanDefinitionRegistryPostProcessors(bean定义注册后置处理器)名称
                // 将查找到的名称集合放置到processedBeans中,以及将后置处理器添加到集合currentRegistryProcessors中
                // 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);
                    }
                }
                //对currentRegistryProcessors集合排序
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                //将当前查找到的currentRegistryProcessors放置到注册后置处理器集合registryProcessors中
                registryProcessors.addAll(currentRegistryProcessors);
                //遍历循环执行currentRegistryProcessors集合中的bean定义注册后置处理器
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                //清空currentRegistryProcessors集合
                currentRegistryProcessors.clear();
    
                // 最后在容器中查找其余BeanDefinitionRegistryPostProcessors(bean定义注册后置处理器)名称
                // 将查找到的名称集合放置到processedBeans中,以及将后置处理器添加到集合currentRegistryProcessors中
                // 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.
                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!
            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.
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            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.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
            beanFactory.clearMetadataCache();
        }
    
    

    此方法比较长,根据传入beanFactory类型可分为两部分:

    1. beanFactory是BeanDefinitionRegistry类型时

    此条件下完成如下流程:

    1. 遍历传入后置处理器集合查找类型为BeanDefinitionRegistryPostProcessor的后置处理器,调用后置处理器的postProcessBeanDefinitionRegistry方法
    2. 在容器中查找所有的实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法如下:
        private static void invokeBeanDefinitionRegistryPostProcessors(
                Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    
            for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }
    
    1. 在容器中查找所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法。
    2. 在容器中查找其它(未实现排序接口)的BeanDefinitionRegistryPostProcessor并添加到集合nonOrderedPostProcessors中,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法
    1. 当前所有的BeanDefinitionRegistryPostProcessor处理器的方法postProcessBeanDefinitionRegistry 执行完毕后,执行其父类postProcessBeanFactory方法
    1. 执行所有非BeanDefinitionRegistryPostProcessor类型的后置处理器的postProcessBeanFactory方法
    1. beanFactory非BeanDefinitionRegistry类型时

    此条件下完成如下流程:

    1. 遍历传入后置处理器集合,执行后置处理器的postProcessBeanFactory方法,如下:
        private static void invokeBeanFactoryPostProcessors(
                Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
             //遍历BeanFactoryPostProcessor集合执行postProcessBeanFactory方法
            for (BeanFactoryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanFactory(beanFactory);
            }
        }
    
    1. 在容器中(beanFactory.getBeanNamesForType)查找所有的实现了PriorityOrdered接口的BeanFactoryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理。
    2. 在容器中查找所有实现了Ordered接口的BeanFactoryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理。
    3. 在容器中查找其它(未实现排序接口)的BeanFactoryPostProcessor并添加到集合nonOrderedPostProcessors中,对后置处理器集合排序,遍历,执行后置处

    BeanFactoryPostProcessor类型

    在上面看到spring主要将BeanFactoryPostProcessor划分了两类:

    • 正常的BeanFactoryPostProcessor
    • BeanDefinitionRegistry类型的BeanDefinitionRegistryPostProcessor

    在执行流程中可以看到spring先执行了BeanDefinitionRegistryPostProcessor类型的postProcessBeanDefinitionRegistry方法,再执行BeanDefinitionRegistryPostProcessor和正常BeanFactoryPostProcessor的postProcessBeanFactory方法。

    spring对BeanDefinitionRegistryPostProcessor的解释是:允许在正常的BeanFactoryPostProcessor执行检测开始之前注册更多的自定义bean。也就是说BeanDefinitionRegistryPostProcessor的方法postProcessBeanDefinitionRegistry可以在后置处理器执行前自定义注册更多的BeanDefinition。

    例如:spring实现的ConfigurationClassPostProcessor用于注册注解@Configuration标识的类里面定义的BeanDefinition


    BeanFactoryPostProcessor 执行的整体流程:

    1. ApplicationContext的refresh方法
    2. ApplicationContext的invokeBeanFactoryPostProcessors方法
    3. PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors

    refresh()-> invokeBeanFactoryPostProcessors()->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

    BeanFactoryPostProcessor执行的优先级:

    1. 首先是实现了PriorityOrdered接口的,排序执行
    2. 下来是实现了Ordered接口的,排序执行
    3. 最后是其它(未实现排序接口),顺序执行

    BeanFactoryPostProcessor获取机制:

    1. 首先获取手动注册ApplicationContext的集合
    2. 再次是通过beanFactory.getBeanNamesForType查找所有已注册的BeanFactoryPostProcessor的bean定义并实例化。






  • 相关阅读:
    正则表达式(常用正则总结)
    What is maven?
    二维数组的遍历使用foreach
    Installing Git
    Hive修改表名,列名,列注释,表注释,增加列,调整列顺序,属性名等操作
    有趣的开源项目集结完毕,HelloGitHub 月刊第 63 期发布啦!
    - zxvf
    tensorflow入门
    Postman v8.7.0
    springboot等javaweb项目将jar包安装(打包)到本地Maven仓库
  • 原文地址:https://www.cnblogs.com/UUUz/p/12170437.html
Copyright © 2011-2022 走看看