<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 · 玖

          共 2799字,需瀏覽 6分鐘

           ·

          2021-09-17 16:35

          前言

          今天我們開始看refresh的最核心方法,這四個(gè)方法剖析完成,spring boot就真的啟動(dòng)成功了:

          • onRefresh
          • registerListeners
          • finishBeanFactoryInitialization
          • finishRefresh

          refresh

          onRefresh

          這個(gè)方法就是初始化特殊子類容器中的特殊bean,這個(gè)方法的具體調(diào)用流程如下:

          首先它先調(diào)用了abstractApplicationContextonRefresh方法,由于這個(gè)是個(gè)抽象類,所以實(shí)際上調(diào)用的是當(dāng)前容器或者其父類繼承了abstractApplicationContext的類的onRefresh方法,實(shí)現(xiàn)onRefresh的類總共有5個(gè):

          但其中只有ServletWebServerApplicationContext是我們當(dāng)前容器的父類,所以實(shí)際上最后調(diào)用的是ServletWebServerApplicationContexonRefresh方法,在它的方法內(nèi)部有兩部分調(diào)用,一個(gè)是調(diào)用父類的onRefresh方法,父類的方法內(nèi)部其實(shí)就是進(jìn)行了themeSource資源的初始化;另一部分,調(diào)用了createWebServer方法,顧名思義,就是創(chuàng)建web服務(wù)器。

          initThemeSource

          先看父類onRefresh的調(diào)用,它的內(nèi)部其實(shí)就是進(jìn)行了主題資源的初始化,準(zhǔn)確地說(shuō)就是進(jìn)行了實(shí)例化和賦值,最后將themeSource返回:

          看了半天才搞明白,原來(lái)這里的themeSource指的就是主題資源,我還在納悶spring boot為啥還需要主題(就是手機(jī)桌面這種主題),最后才發(fā)現(xiàn)原來(lái)是給消息資源使用,主要包括css、圖片等資源:

          createWebContext

          這個(gè)方法就是為了創(chuàng)建webServer,這一點(diǎn)從名字就可以看出來(lái):

          默認(rèn)情況下webServerservletContext都是null,所以會(huì)創(chuàng)建webServer實(shí)例,默認(rèn)情況下創(chuàng)建的是TomcatWebServer的實(shí)例,創(chuàng)建完成后會(huì)往beanFactory中注冊(cè)webServer的兩個(gè)生命周期實(shí)例,一個(gè)是shutdown,一個(gè)是startStop,這兩個(gè)生命周期主要是用來(lái)控制服務(wù)啟停的。

          registerListeners

          這個(gè)方法就是注冊(cè)監(jiān)聽(tīng)器,而且方法注釋上也寫的很清楚:校驗(yàn)并注冊(cè)監(jiān)聽(tīng)器

          內(nèi)部實(shí)現(xiàn)也很簡(jiǎn)單,首先是往應(yīng)用事件廣播器中添加監(jiān)聽(tīng)器;

          然后還把監(jiān)聽(tīng)器的beanName注冊(cè)進(jìn)應(yīng)用監(jiān)聽(tīng)器的接收器(defaultRetriever)列表中,而且這里注釋的很清楚:這里不初始化FactoryBeans

          最后是推送應(yīng)用預(yù)刷新事件(也就是我們第陸部分的內(nèi)容,這里的監(jiān)聽(tīng)器是在prepareRefresh方法中進(jìn)行初始化的)

          finishBeanFactoryInitialization

          從名字就可以看出來(lái),這個(gè)方法就是完成最后的beanFactory初始化,方法注釋也說(shuō)的很清楚,會(huì)初始化剩余的單例bean

          方法主要有四塊內(nèi)容,第一塊是設(shè)置beanFacory的轉(zhuǎn)換服務(wù),我就說(shuō)這一塊的代碼咋看著有點(diǎn)眼熟,原來(lái)是在分析prepareContext方法的時(shí)候,當(dāng)時(shí)也有調(diào)用這個(gè)方法。

          第二塊是注冊(cè)已經(jīng)嵌入的配置值的解析器,這里是lambda的寫法,這注冊(cè)的應(yīng)該是對(duì)$Value{name}這樣的配置的解析器

          第三塊是獲取加載時(shí)間織入器,但是有一點(diǎn)我有點(diǎn)看不懂,getBean是有返回值的,這里也沒(méi)有接收,所以這里調(diào)用只是為了校驗(yàn)?

          第四塊就是調(diào)用beanFactory的三個(gè)方法,首先是調(diào)用setTempClassLoader置為null,官方給的注釋是停止使用臨時(shí)加載器;然后調(diào)用freezeConfiguration方法,官方給的注釋是僅獲取bean的定義元數(shù)據(jù),不做其他操作;最后調(diào)用preInstantiateSingletons方法,從方法名來(lái)看這個(gè)方法會(huì)進(jìn)行單例bean的預(yù)初始化操作,官方給的注釋是實(shí)例化剩余的單例。

          下面我們?cè)敿?xì)看下freezeConfigurationpreInstantiateSingletons,先看freezeConfiguration方法:

          本以為這個(gè)方法內(nèi)部實(shí)現(xiàn)很復(fù)雜,點(diǎn)進(jìn)來(lái)才發(fā)現(xiàn)就兩行代碼,第一行將configurationFronzen設(shè)置為true,這個(gè)屬性用于標(biāo)記bean的定義元數(shù)據(jù)是否已經(jīng)被緩存。

          第二行是將bean定義名賦值給frozenBeanDefinitionNames,從名字推測(cè)這個(gè)應(yīng)該是為了凍結(jié)bean定義名,這也就意味著在這個(gè)方法執(zhí)行之后,不會(huì)再注冊(cè)新的bean定義名。

          下面我們看第四塊的第三個(gè)方法——preInstantiateSingletons,這個(gè)方法主要有兩大塊內(nèi)容,一塊是實(shí)例化非懶加載的bean(通過(guò)getBean方法,看來(lái)我對(duì)這個(gè)方法理解的不夠透徹,但是這個(gè)方法內(nèi)部并沒(méi)有進(jìn)行newInstance這樣的操作,而是直接從beanbeanFactory中獲取);

          另一塊是初始化后,回調(diào)操作。這里的doPrivileged方法是java.security包下提供的一個(gè)特權(quán)操作,關(guān)于這一塊后面需要深入研究下。這個(gè)doPrivileged內(nèi)部調(diào)用了afterSingletonsInstantiated,這個(gè)方法在單例實(shí)例化完成后調(diào)用,就是我們說(shuō)的回調(diào)操作

          finishRefresh

          這個(gè)方法就是完成最后的清理工作,同時(shí)會(huì)初始化容器的生命周期處理器,然后執(zhí)行容器生命周期的刷新操作,最后會(huì)推送啟動(dòng)刷新完成事件

          總結(jié)

          緊趕慢趕,四個(gè)方法總算全部分享完了,差一點(diǎn)點(diǎn)就分析不完了,而且最后一個(gè)方法實(shí)在分析地有點(diǎn)拉垮。

          總之,關(guān)于這兩天的內(nèi)容更新,我總結(jié)出來(lái)兩點(diǎn):

          第一,周末效率有點(diǎn)低下,沒(méi)玩好也沒(méi)學(xué)好,特別容易被打擾,內(nèi)容輸出還是要找一個(gè)安靜、舒適的環(huán)境,這樣精力比較集中;

          第二,spring boot真的上頭呀。感覺(jué)run方法的核心代碼都已經(jīng)分析完了,但我咋發(fā)現(xiàn),我好像還是沒(méi)理清楚spring boot的啟動(dòng)流程呢?或者更準(zhǔn)確的說(shuō)是感覺(jué)目前分析的內(nèi)容和我預(yù)期的是有差異的,而且差異很大,具體的差異感覺(jué)得等我把run方法整體分析完,再回過(guò)頭來(lái)總結(jié),才能得出結(jié)論。現(xiàn)在感覺(jué)好像懂了,但是又沒(méi)完全懂,說(shuō)不懂吧,整體的知識(shí)更清晰了,感覺(jué)還是很朦朧。

          確實(shí)有點(diǎn)上頭了,而且spring boot的類名和方法名還老長(zhǎng),經(jīng)常比對(duì)方法名比對(duì)半天……說(shuō)多了都是淚,怕不是有點(diǎn)走火入魔了吧,趕快結(jié)束吧,后面要慢慢花時(shí)間消化了……

          - END -


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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  色欲av伊人久久大香线蕉影院 | 人人看人人摸人人透 | 国产乱伦一区 | 超碰99免费 | 免费a v在线 |