目前咱们剖析的代码曾经到了容器解决相干的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);   //其余逻辑}

曾经剖析的阶段如下图:

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的实例化

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

当然除了外围给大家剖析下面这三个办法,其余的会顺带提到下,让大家理解下就行。

明天咱们就来先refresh的看看第一个外围办法做了什么。

invokeBeanFactoryPostProcessors执行容器扩大点之前的次要操作

refresh()执行到invokeBeanFactoryPostProcessors是十分重要的逻辑,后面的办法大体能够概括如下图所示:

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

波及设置了一些无关紧要的值,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,这个显著不是啥重点逻辑,之前做过很多相似的操作了。

如下图所示:

那你深刻到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循环

如下图:

好了,这就是这个办法的外围脉络了,接下来咱们别离来弄清楚,if-else逻辑在做什么,之后的3个for循环在做什么,这个办法根本就晓得在做什么了。

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

if-esle外围脉络逻辑

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

BeanDefinitionRegistry这个接口,之前咱们遍及过,封装了对BeanDefinition常见操作的接口,容器默认实现了这个接口,所以个别它也代表了容器,能够通过实现的办法,保护容器内List<BeanDefinition>。

代码如下:

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<BeanFactoryPostProcessor> beanFactoryPostProcessors。

这个属性时之前通过listener等扩大点减少进来的一些Spring外部的BeanFactoryPostProcessor。次要有如下三个:

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

咱们这里把它们称之为inernalBeanFactoryPostProcessors

如下图:

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

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

if逻辑

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

这里要先遍及一些概念,才能够更好的了解if的代码逻辑。

术语遍及BeanDefinitionRegistryPostProcessor是什么?

BeanDefinitionRegistryPostProcessor也是扩大点,继承自BeanFactoryPostProcessor,对BeanFactoryPostProcessor减少了一个扩大办法而已。

整体设计如下图所示:

BeanFactoryPostProcessor能够有两个扩大操作

也就是说,原来的BeanFactoryPostProcessor的扩大办法,从一个减少到了两个,一个是postProcessBeanFactory(),另一个事postProcessBeanDefinitionRegistry()。

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

1)容器中,当时通过扩大点退出的BeanFactoryPostProcessor

2)BeanDefinition中的,定义的然而没有实例化的BeanFactoryPostProcessor

如下图:

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。

次要逻辑能够概括如下图:

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

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()。

如下图所示:

整个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的执行形式,执行了如下的扩大操作:

3个for的逻辑的脉络,其实并不简单,至于这些扩大操作具体做了什么,既然咱们摸清楚了整个办法invokeBeanFactoryPostProcessors的脉络了,咱们下一节马上就来剖析。

小结

最初,简略小结下,invokeBeanFactoryPostProcessors次要做的就是执行BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor的2个扩大办法。这些BeanFactoryPostProcessors可能是外部Spring实现增加好的,也可能是来自ClassPath扫描进去的BeanFactoryPostProcessors。

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

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