1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        spring-boot源碼分析之BeanFactory · 陸

        共 2691字,需瀏覽 6分鐘

         ·

        2021-09-12 22:01

        前言

        從今天開始,我們要啃硬骨頭了——refreshContext。這個(gè)方法就是我們一直在說的spring boot最核心的方法,這個(gè)方法執(zhí)行完成后,spring boot基本上就初始化完了,剩下的方法就是推送啟動(dòng)事件,回調(diào)相關(guān)的監(jiān)聽器之類的,反正就是吃透refresh方法,基本上就可以宣告革命勝利了,換句話說,就是如果我們啃下這塊硬骨頭之后,spring boot啟動(dòng)這塊我們就算徹底剖析完了,剩下的都是查漏補(bǔ)缺的小知識(shí)點(diǎn)了,摟草打兔子,順手的事。

        好了,大話就說這么多,下面我們開始干活~

        refreshContext

        容器的刷新首先是從refreshContext方法開始的,然后refreshContext方法內(nèi)部會(huì)調(diào)用容器的refresh方法。

        這里 refreshContext就做了兩件事,一個(gè)是注冊(cè)容器關(guān)閉鉤子函數(shù),另外一個(gè)就是刷新容器。

        關(guān)閉鉤子函數(shù)可以讓我們更優(yōu)雅地關(guān)閉spring boot容器,這一塊后期也專門分享一次;刷新容器方法最終會(huì)調(diào)用容器的刷新方法,關(guān)于這個(gè)方法,我們之前已經(jīng)分享過了,t它的作用就是刷新容器中的持久化資源,這里的資源包括xml、java配置、注解、配置文件、數(shù)據(jù)庫等。

        下面,我們就來詳細(xì)看下它的內(nèi)部實(shí)現(xiàn)。我們先看下它的調(diào)用流程:

        從上面圖中我們可以看出來,最終其實(shí)調(diào)用的是AbstractApplicationContextrefresh方法,這個(gè)方法內(nèi)部比較長(zhǎng),總共調(diào)用了15個(gè)方法,下面我們就逐一剖析這些方法,不過工作日時(shí)間有限,今天可能也分享不了太多內(nèi)容,具體視情況而定吧。

        prepareRefresh

        我們先說prepareRefresh方法,這個(gè)方法的作用就是為后面的刷新操作做準(zhǔn)備,內(nèi)部實(shí)現(xiàn)如下:

        簡(jiǎn)單解釋下它的執(zhí)行流程:

        • 首先設(shè)置spring boot的啟動(dòng)時(shí)間,獲取的是當(dāng)前時(shí)間;

        • 然后分別設(shè)置closedactiveflasetrue,這兩個(gè)屬性都是原子類AtomicBoolean

        • 接著會(huì)根據(jù)日志設(shè)置等級(jí)輸出日志,不過這里必須是begug級(jí)別才會(huì)輸出,如果是trace等級(jí)的,則會(huì)輸出更詳細(xì)的日志信息。

        • 再然后,它會(huì)調(diào)用initPropertySources方法,這個(gè)方法的作用就是進(jìn)行配置資源初始化初始化,我們等下詳細(xì)剖析;

        • 再下面就是資源的校驗(yàn),這塊也需要展開分析

        • 最后是監(jiān)聽器和監(jiān)聽事件的賦值操作

        initPropertySources

        initPropertySources方法進(jìn)行的就是property資源的初始化,當(dāng)前容器并沒有重寫該方法:

        由于 AbstractApplicationContextinitPropertySources 方法是空實(shí)現(xiàn),而且AnnotationConfigServletWebServerApplicationContext并沒有重寫該方法,所以最后調(diào)用的是父類GenericWebApplicationContext的這個(gè)方法,父類的方法中最后調(diào)用的是ConfigurableWebEnvironment的配置資源初始化方法:

        在方法內(nèi)部,首先通過getEnvironment方法獲取系統(tǒng)的環(huán)境設(shè)置,然后同獲取到的環(huán)境設(shè)置進(jìn)行配置資源初始化,其中servletConfig的入?yún)⒅苯訛?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">null。

        關(guān)于這里獲取到的ConfigurableWebEnvironment,我們做一點(diǎn)點(diǎn)擴(kuò)展補(bǔ)充,ConfigurableWebEnvironment主要的屬性是profiles和資源解析器,這里的defaultProfiles表示spring boot的默認(rèn)配置文件,activeProfiles表示spring boot啟動(dòng)時(shí)激活的配置文件,從下面截圖也可以很清楚看出來:

        關(guān)于profile文件,相比各位小伙伴應(yīng)該都不陌生,在spring boot中我們的配置文件就叫profile,默認(rèn)情況下的配置文件是application.*,文件類型可以是properties文件或者yaml文件,我們通常通過spring.profiles.active=@profileActive@(``yml`方式類似)指定需要激活的文件(環(huán)境配置)

        獲取完配置資源之后,會(huì)調(diào)用ConfigurableWebEnvironmentinitPropertySources方法,下面是initPropertySources方法的內(nèi)部調(diào)用流程。在debug過程中,我發(fā)現(xiàn)默認(rèn)情況下servletContextservletConfig都為空,所以replace方法實(shí)際并未執(zhí)行。

        validateRequiredProperties

        這里校驗(yàn)是根據(jù)我們AbstractPropertyResolver解析器的requiredProperties屬性進(jìn)行判斷的,如果存在為空的配置就會(huì)報(bào)錯(cuò),說這個(gè)方法內(nèi)部實(shí)現(xiàn)也很簡(jiǎn)單,流程也不是很復(fù)雜,就是一些簡(jiǎn)單的資源獲取和空判斷:

        這里的requiredPropertiesenvironment有關(guān),它是AbstractEnvironmentsetRequiredProperties方法中初始化的,關(guān)于這個(gè)方法的調(diào)用,等我們回頭分析environment初始化的時(shí)候再來研究。

        監(jiān)聽器賦值

        prepareRefresh0方法的最后就是一些監(jiān)聽器集合的賦值操作,earlyApplicationListeners表示預(yù)刷新容器應(yīng)用監(jiān)聽器集合(pre-refresh ApplicationListeners),applicationListeners表示當(dāng)前容器監(jiān)聽器集合,earlyApplicationEvents就表示預(yù)刷新應(yīng)用監(jiān)聽事件。

        其實(shí)也就是監(jiān)聽器的初始化,代碼也很簡(jiǎn)單,加上注釋就很容器理解,我也就不再贅述了。

        總結(jié)

        今天效率有點(diǎn)低呀,一整天就搞定了一個(gè)方法,確實(shí)有些離譜,但是也沒辦法,今天事情確實(shí)比較多——今天我負(fù)責(zé)處理oncall問題,然后下午又開了三個(gè)多小時(shí)的會(huì),下班那會(huì)還在排查處理線上問題,有點(diǎn)難呀~

        不過,好在之前已經(jīng)把今天的內(nèi)容寫的七七八八了,不然今天新內(nèi)容就懸了……剛剛又看了下剩余的內(nèi)容,明天應(yīng)該可以搞定3個(gè)方法,然后還剩11個(gè)方法,后天4個(gè),大后天4個(gè),周一安排3個(gè),完美,所以今天就先到這里吧~

        - END -


        瀏覽 56
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            www.欧美成人 | 男生插女生阴道视频 | 日日夜夜综合网 | 操逼视频能看的 | 91免费黄色电影 | 日本无码成人片在线观看波多 | 国产又大又硬又爽免费视频试 | 裸体欧美军警猛男gay | 很黄很污的视频在线观看 | 成人免费看片169 |