<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          spring-boot源碼分析之BeanFactory · 壹

          共 5615字,需瀏覽 12分鐘

           ·

          2021-09-06 15:38


          前言

          今天原本是打算分析beanFactory的,但由于昨天我們有一部分內(nèi)容還沒有分享完,所以今天就先開個倒車,把昨天的內(nèi)容先講清楚了再說別的,因此今天的內(nèi)容主要就是對昨天分享內(nèi)容的的補(bǔ)充。

          當(dāng)然,昨天我們分享的內(nèi)容beanDefinitionNames也算是BeanFactory的核心屬性,所以也不能說完全沒有關(guān)系:

          而且從源碼中我們可以看出來,beanDefinitionNamesbeanDefinitionMap這些屬性的初始化大小,這也算是在學(xué)習(xí)beanFactory的相關(guān)知識吧。

          BeanFactory

          beanDefinitionNames內(nèi)容補(bǔ)充

          正式開始之前,我們先把昨天遺留的問題解決了。昨天,我們分享了一張beanDefinitionNames初始化的時序圖,但是由于有一些內(nèi)容沒有梳理清楚,所以這里先做個補(bǔ)充。

          調(diào)用過程各方法作用

          SpringApplication這里就不做過多說明了,我們在前面最開始的時候就已經(jīng)分析過這個類的run方法,當(dāng)時也已經(jīng)介紹過這個類的這些方法,他們的主要作用就是為了初始化容器,在SpringApplication的最后一個refresh方法中,最后會調(diào)用AbstractApplicationContext自身的refresh方法,這里的AbstractApplicationContextApplicationContext的抽象實(shí)現(xiàn),它實(shí)現(xiàn)了ConfigurableApplicationContext接口(ConfigurableApplicationContext繼承了ApplicationContext),我們的AnnotationConfigReactiveWebServerApplicationContext(默認(rèn)容器)就是繼承自它,不過并不是直接繼承,它的父類繼承了AbstractApplicationContext,關(guān)于容器這塊的繼承關(guān)系,我們改天抽個時間,專門分析下。

          大部分繼承了AbstractApplicationContext的容器都沒有重寫refresh方法,就算重寫了這個方法,其內(nèi)部也是調(diào)用了父類的refresh方法:

          我們看下refresh的實(shí)現(xiàn)源碼:

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

          refresh方法內(nèi)部,調(diào)用了很多其他方法,其中prepareRefresh的作用是為我們下面的刷新操作做準(zhǔn)備,其內(nèi)部主要是對配置的一些初始化操作:

          obtainFreshBeanFactory方法的作用是刷新beanFactory,主要是對beanFactory進(jìn)行一些初始化操作,如果beanFactory已經(jīng)存在,會將已有的beanFactory銷毀,然后重新創(chuàng)建,最后將beanFactory返回:

          prepareBeanFactory方法的作用是對BeanFactory進(jìn)行一些賦值和設(shè)置,為容器初始化操作做準(zhǔn)備:

          postProcessBeanFactory方法就是我們昨天提到的會進(jìn)行包掃描的那個方法,但由于basePackagesannotatedClasses都是空,所以其中的scan方法并不會被執(zhí)行。這個方法實(shí)際的作用是,后置處理BeanFactory

          invokeBeanFactoryPostProcessors方法的作用是,實(shí)例化并調(diào)用所有注冊的BeanFactory的后置處理器。我們昨天說的beanDefinitionNamesbeanDefinitionMap就是通過這個方法最終完成初始化的:

          registerBeanPostProcessors方法和它名字一樣,它的作用就是注冊bean的后置處理器:

          initMessageSource方法是進(jìn)行消息源初始化的,主要是對web應(yīng)用消息國際化提供支持的:

          initApplicationEventMulticaster,這個方法是初始化spring boot應(yīng)用時間廣播的,如果不指定的話,默認(rèn)情況下為我們指定的是SimpleApplicationEventMulticaster

          onRefresh,這個方法是提供給子類初始化其他特殊bean對象的,默認(rèn)實(shí)現(xiàn)為空,子類可根據(jù)需要重寫:

          registerListeners方法是用來注冊事件監(jiān)聽器的:

          finishBeanFactoryInitialization,完成beanFactory初始化,同時在方法內(nèi)部會實(shí)例化剩余的單例類(不包括懶加載部分):

          finishRefresh,完成刷新,主要進(jìn)行一些清理、刷新、事件推送等操作:

          總結(jié)

          經(jīng)過今天的補(bǔ)充之后,我相信各位小伙伴一定也對spring boot的啟動和初始化過程有了更深刻的認(rèn)識,因?yàn)槲揖褪沁@樣的感受。相比于昨天分享完內(nèi)容的感受,今天我感覺整體來說要更好。一方面感覺spring boot啟動和初始化的流程更清晰了,而且由于最近這幾天一直在看spring boot的源碼,看的多了感覺就沒有那么難了,畢竟書讀百遍其意自現(xiàn),代碼也是大同小異;另一方面在梳理分析的過程中,讓我也能夠清晰地看到下一步要分享的內(nèi)容,明確后面的前進(jìn)方向,這也算是意外的收獲吧。

          - END -


          瀏覽 38
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成人性爱在线视频免费 | 天天操天天干天天操 | 欧美性猛交99久久久久99按摩 | 婷婷丁香社区 | 免费黄色A片视频 |