SpringBoot成长记7:容器的扩展操作是如何执行的

file

目前我们分析的代码已经到了容器处理相关的SpringBoot原理,代码如下:

public ConfigurableApplicationContext run(String... args) {
   //DONE 扩展点 SpringApplicationRunListeners listeners.starting();

   //DONE 配置文件的处理和抽象封装 ConfigurableEnvironment

   //容器相关处理
   //1)核心就是创建了Context和BeanFactory对象,内部初始化了Reader和Scanner,加载了一些内部Bean
   context = createApplicationContext();
   exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                          new Class[] {ConfigurableApplicationContext.class }, context);
    //2) 给容器Context、BeanFactory设置了一堆属性和组件,执行了initialize/listener的扩展点
    //比较重要属性有:singletonObjects 、beanDefinitionMap 、beanFactoryPostProcessors、applicationListeners
    prepareContext(context, environment, listeners, applicationArguments,printedBanner);
    //3) TODO 容器关键的扩展操作执行了,也是很多容器功能和第三方功能的扩展之处
    refreshContext(context);
   //其他逻辑
}

已经分析的阶段如下图:

file

prepareContext()准备完成之后,接下来就是refreshContext()。容器关键的扩展操作执行了,也是很多容器功能和第三方功能的扩展之处,我们来一起看下吧。

快速摸一下refreshCotenxt的脉络

refreshCotenxt()方法最终调用了容器的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.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                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();
            }
        }
    }

整体由一个try-catch构成,内部有很多个方法组成,看上去让人找不到重点所在,感觉每个方法都挺重要的。

我第一次看的时候,每个方法,都分开从脉络到细节,分析。

最后抓大放小,其实refresh在上面最重要的三个方法是:

invokeBeanFactoryPostProcessors 执行了容器扩展点,自动装配配置、其他技术的常扩展处

onRefresh 内嵌的web容器启动,默认是tomcat

finishBeanFactoryInitialization bean的实例化

file

那么,本着抓大放小的思想,其余的方法不是很重要,这个确认过程就不带大家一一去展开看每个方法了。

当然除了核心给大家分析上面这三个方法,其他的会顺带提到下,让大家了解下就行。

今天我们就来先refresh的看看第一个核心方法做了什么。

invokeBeanFactoryPostProcessors执行容器扩展点之前的主要操作

refresh()执行到invokeBeanFactoryPostProcessors是非常重要的逻辑,前面的方法大体可以概括如下图所示:

file

整个过程中,不是很重要,用浅蓝色标注的内容

涉及设置了一些无关紧要的值,startupDate、setSerializationId、BeanExpressionResolver等等

也设涉及了基本对象集合的初始化earlyApplicationEvents、earlyApplicationListeners

也标注了几个容器注入对象需要特别考虑和忽略的接口等

setignoreDependencyInterface 设置忽略的接口,不会注册成bean

registerResolvableDependency 指明Spring内部一些接口 默认会注入的容器对象

相对重要一点的点是,图中用绿色标注了下

主要还补充了一些Spring自己的对Bean的扩展点BeanPostProcessor,Spring默认的BeanPostProcessor,补充一些BeanDefinition、registerSingleton补充一些内部的对象到集合。

术语普及BeanPostProcessor是什么?

之前BeanFactoryPostProcessor是对容器的扩展,主要有一个方法,可以给容器设置属性,补充一些单例对象,补充一些BeanDefinition。

那BeanPostProcessor是对bean的扩展,有before和after两类方法,对Bean如何做扩展,在bean的创建前后,给bean补充一些属性等。

invokeBeanFactoryPostProcessors之前的逻辑,我们快速过一下就好,当中并没有特别重要的逻辑,主要是Spring对内部的处理,给容器补充了一堆属性。

invokeBeanFactoryPostProcessors的核心脉络

大体了解了invokeBeanFactoryPostProcessors之前的主要操作后,接下来我们核心首先来先看看这个方法的脉络,看看它主要做了写什么的?

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

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

乍一看,这个方法好像挺简单的, 只有2段逻辑,你很容易抓到重点

invokeBeanFactoryPostProcessors执行扩展点,这个应该是核心触发容器的扩展点地方。

根据条件,补充一个Bean的扩展操作,BeanPostProcessor,这个明显不是啥重点逻辑,之前做过很多类似的操作了。

如下图所示:

file

那你深入到PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors这个方法是,你会发现如下一大坨的代码:

    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set<String> processedBeans = new HashSet<>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    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<>();

            // 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);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 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();

            // 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<>(orderedPostProcessorNames.size());
        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<>(nonOrderedPostProcessorNames.size());
        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)首先主要有一个if-else组成

2)之后是连续的3个for循环

如下图:

file

好了,这就是这个方法的核心脉络了,接下来我们分别来弄清楚,if-else逻辑在做什么,之后的3个for循环在做什么,这个方法基本就知道在做什么了。

让我们来看下第一个if-else在做什么呢?

if-esle核心脉络逻辑

第一个if-esle核心逻辑主要是判断了容器是否实现了BeanDefinitionRegistry这个接口,从而决定如何执行BeanFactoryPostProcessor的扩展操作。

BeanDefinitionRegistry这个接口,之前我们普及过,封装了对BeanDefinition常见操作的接口,容器默认实现了这个接口,所以一般它也代表了容器,可以通过实现的方法,维护容器内List 。

代码如下:

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    if (beanFactory instanceof BeanDefinitionRegistry) {

    }else {
       // Invoke factory processors registered with the context instance.
       invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
}

容器默认是实现了BeanDefinitionRegistry接口,正常会执行if逻辑。由于if逻辑相对复杂,我们先来看下,else逻辑在做什么,再去理解if逻辑。

else逻辑

else逻辑比较简单主要就是触发了入参中的beanFactoryPostProcessors的扩展方法postProcessBeanFactory(),代码如下:

private static void invokeBeanFactoryPostProcessors(
    Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

疑问:入参中这些内部的BeanFactoryPostProcessor这个是哪里来的?

是通过从容器中的一个属性 List beanFactoryPostProcessors。

这个属性时之前通过listener等扩展点增加进来的一些Spring内部的BeanFactoryPostProcessor。主要有如下三个:

beanFactoryPostProcessors = {ArrayList@2882}  size = 3
 0 = {SharedMetadataReaderFactoryContextInitializer
 $CachingMetadataReaderFactoryPostProcessor@2887} 
 1 = {ConfigurationWarningsApplicationContextInitializer
 $ConfigurationWarningsPostProcessor@2888} 
 2 = {ConfigFileApplicationListener
 $PropertySourceOrderingPostProcessor@2889} 

我们这里把它们称之为inernalBeanFactoryPostProcessors

如下图:

file

那最终else逻辑其实主要就是触发了这些内部BeanFactoryPostProcessor的postProcessBeanFactory()扩展方法而已。整体如下图所示:

file

至于这些扩展操作具体做了什么,我们稍后在分析,先整体摸清楚方法脉络在来看细节。

if逻辑

了解了else 的逻辑之后,我们再看下if主要做了什么。因为if-else逻辑,其实默认是不会执行的else的,优先执行的肯定是if。

这里要先普及一些概念,才可以更好的理解if的代码逻辑。

术语普及BeanDefinitionRegistryPostProcessor是什么?

BeanDefinitionRegistryPostProcessor
也是扩展点,继承自BeanFactoryPostProcessor,对BeanFactoryPostProcessor增加了一个扩展方法而已。

整体设计如下图所示:

file

BeanFactoryPostProcessor可以有两个扩展操作

也就是说,原来的BeanFactoryPostProcessor的扩展方法,从一个增加到了两个,一个是postProcessBeanFactory(),另一个事postProcessBeanDefinitionRegistry()。

另外一个要强调的其实是BeanFactoryPostProcessor来源有两个

1)容器中,事先通过扩展点加入的BeanFactoryPostProcessor

2)BeanDefinition中的,定义的但是没有实例化的BeanFactoryPostProcessor

如下图:

file

BeanFactoryPostProcessor可以有两个扩展操作BeanFactoryPostProcessor来源有两个

这2点很关键,带着这个知识,我们再看if逻辑,就会很容易。

if逻辑主要代码如下:

if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    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<>();

            // 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);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // 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();

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

这个if逻辑的代码脉络,主要的逻辑是有3个for+1while逻辑,其实可以按照扩展操作1和扩展操作2的执行划分开。

让我们分别看下。

执行扩展方法1:postProcessBeanDefinitionRegistry()

执行扩展方法1时,首先就需要分别从两个来源开始执行,而且执行的是实现了BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor。

主要逻辑可以概括如下图:

file

用文字解释下上图的话,就是:

1)容器中,之前增加的内部相关的BeanFactoryPostProcessor有没有实现这个BeanDefinitionRegistryPostProcessor接口增加了扩展方法postProcessBeanDefinitionRegistry()的?如果有,对应的所有BeanFactoryPostProcessor,通过for循环执行这个方法。并且记录这些执行的BeanFactoryPostProcessor和未执行的BeanFactoryPostProcessor。

2)容器中,之前增加的内部相关的BeanDefinition中,有没有定义为BeanFactoryPostProcessor的,如果有,按照实现了PrioriyOrder接口、Order接口、无Order接口的分别执行扩展方法postProcessBeanDefinitionRegistry(),使用了2for循环+一个while循环执行,执行完成记录这些BeanFactoryPostProcessor。

执行扩展方法2:postProcessBeanFactory()

之前执行扩展方法1的时候记录的所有BeanFactoryPostProcessor,包括扩展点之前添加的,BeanDefinition定义的。

我们可以通过记录的这些BeanFactoryPostProcessor ,来在执行执行扩展方法2—postProcessBeanFactory()。

如下图所示:

file

整个if-else的逻辑的脉络,我们就摸清楚了,至于这些扩展操作具体做了什么,我们稍后在分析,还是先整体摸清楚方法脉络在来看细节。

3个For循环的核心脉络逻辑

invokeBeanFactoryPostProcessors的核心脉络中,除了一个if-else逻辑,接下来的就是连续的3次for循环执行。

分为主要排序、排序、无顺序要求的BeanFactoryPostProcessor三类,主要执行扩展点BeanFactoryPostProcessor的postProcessBeanFactory方法。

这个逻辑听上去,其实和之前if-else中的逻辑是很像的。只不过之前执行的是BeanDefinitionRegistryPostProcessor。

而且此时的BeanFactoryPostProcessor都来自与BeanDefinition中的。

你可能说,之前已经执行过了BeanDefinition中的BeanFactoryPostProcessor了,怎么还有?

之前执行的是Spring内部定义好的一些BeanFactoryPostProcessor,在执行了if-else逻辑后,其实扫描出来了ClassPath下更多第三方和其他的BeanFactoryPostProcessor

这些新扫描出来BeanFactoryPostProcessor,参考之前BeanDefinitionRegistryPostProcessor的执行方式,执行了如下的扩展操作:

file

3个for的逻辑的脉络,其实并不复杂,至于这些扩展操作具体做了什么,既然我们摸清楚了整个方法invokeBeanFactoryPostProcessors的脉络了,我们下一节马上就来分析。

小结

最后,简单小结下,invokeBeanFactoryPostProcessors主要做的就是执行BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor的2个扩展方法。这些BeanFactoryPostProcessors可能是内部Spring实现添加好的,也可能是来自ClassPath扫描出来的BeanFactoryPostProcessors。

这些扩展点具体执行了写什么,有哪些重点操作呢?我们下一节一起来仔细看看细节。我们下节再见!

本文由博客一文多发平台 OpenWrite 发布!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值