Spring后置器postProcess的源码解析(一)

作者: 激情的狼王 | 来源:发表于2017-12-04 17:12 被阅读0次

    Spring中两种后置器我们在前面文章知道了Spring中bean工厂后置处理器(BeanFactoryPostProcessor)使用Spring中bean后置处理器BeanPostProcessor的用法。
    这两种后置器在Spring中的地位举重若轻,我们看一下Spring初始化的refresh()方法,我只注释到了目前我们已经研究过的部分,后续的我们持续阅读源码,持续注释:

    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                //设置环境变量和容器的开关标志
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                //刷新beanFactory,删除旧的beanFactory,创建新的beanFactory
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                // 准备beanfactory来使用这个上下文.做一些准备工作,例如classloader,beanPostProcessor等 
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    //执行注册到该上下文的BeanFactoryPostProcessors  
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }
    

    上图中我们进展快到一半的位置了,今天研究bean工厂后置器的执行过程,invokeBeanFactoryPostProcessors的作用是执行容器里的BeanFactoryPostProcessorsbean工厂后置器

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
        }
    

    这里调用了PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());这个方法的第二个参数是获取到的Spring容器里的BeanFactoryPostProcessors对象集合。接下来就是今天的核心方法了:

    public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // Invoke BeanDefinitionRegistryPostProcessors first, if any.
            Set<String> processedBeans = new HashSet<String>();
    (1)第一大部分
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
                List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                        new LinkedList<BeanDefinitionRegistryPostProcessor>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryPostProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryPostProcessors.add(registryPostProcessor);
                    }
                    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.
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
                // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
                List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
                registryPostProcessors.addAll(priorityOrderedPostProcessors);
                invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
    
                // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                        orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(beanFactory, orderedPostProcessors);
                registryPostProcessors.addAll(orderedPostProcessors);
                invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
    
                // 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)) {
                            BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                            registryPostProcessors.add(pp);
                            processedBeans.add(ppName);
                            pp.postProcessBeanDefinitionRegistry(registry);
                            reiterate = true;
                        }
                    }
                }
    
                // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
                invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                // Invoke factory processors registered with the context instance.
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    (2)第二大部分,我们要分析的主体
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
    //获取所有继承了BeanFactoryPostProcessor接口的beanNames
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            List<String> orderedPostProcessorNames = new ArrayList<String>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    //把所有的BeanFactoryPostProcessors进行分类
            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(beanFactory, priorityOrderedPostProcessors);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            sortPostProcessors(beanFactory, orderedPostProcessors);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
            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();
        }
    

    上面代码中,总共标注了两大部分。

    第一部分(可忽略):

    1.判断beanFactory是否继承了BeanDefinitionRegistry类
    2.获取BeanDefinitionRegistryPostProcessor的集合
    3.将集合的后置器分类,然后各自分顺序执行。

    第二部分也就是执行我们定义的后置器了
    (大家可以对照源码里的注释来看下面的步骤):

    1.通过beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);方法获取beanFactory里继承了BeanFactoryPostProcessor接口的name的集合;
    2.把这些BeanFactoryPostProcessors进行分类,源码如下

    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);
                }
    }
    

    3.把后置器beans分为PriorityOrdered、Ordered、nonOrdered三大类,前两类是增加了排序条件的后置器;
    4.前两类后置器执行sortPostProcessorsinvokeBeanFactoryPostProcessors方法,也就是先执行排序方法,后执行invoke方法。
    5.最后一类也就是我们例子中定义的,直接执行invoke就可以。

    到这里我们已经了解了refresh()中的invokeBeanFactoryPostProcessors(beanFactory);方法,它的作用是注册并执行我们在bean.xml里定义的BeanFactoryPostProcessors,这里也就解释了为什么Spring初始化先执行BeanFactoryPostProcessors后执行构造函数、init-method等其它方法了。
    后续我们继续跟进spring的初始化源码。

    相关文章

      网友评论

        本文标题:Spring后置器postProcess的源码解析(一)

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