spring-boot源碼分析之beanDefinitionNames · 壹

前言
今天原本打算搞清楚spring boot初始化scan的流程的,但是在調(diào)試過程中,發(fā)現(xiàn)壓根就沒有執(zhí)行scan方法,這個方法只有basePackage不為空的時候才會執(zhí)行,起初我以為是需要在@SpringBootApplication指定包路徑才可以,但是加了之后發(fā)現(xiàn)還是沒用,所以最后就暫時放棄了:

然后我就不知道該分享什么了……
但是最后我在debug的時候,發(fā)現(xiàn)beanFactory有個 beanDefinitionNames的成員變量,它的元素數(shù)量會在reflush方法執(zhí)行之后急劇增加,同時也有個與之對應(yīng)的成員變量beanDefinitionMap元素數(shù)量和它一致,也是在reflush之后數(shù)據(jù)量增多,而且從名字也可以看出來他們和spring bean相關(guān)的組件,另外他們所存儲的數(shù)據(jù)包含了我自己定義的服務(wù):

所以最后我決定沿著beanFactory的beanDefinitionNames的初始化路線,看下這些數(shù)據(jù)到底是如何初始化的,希望最后能更接近spring boot初始化的核心秘密,于是就有了今天的內(nèi)容。
beanDefinitionNames
開始分享beanDefinitionNames相關(guān)知識點之前,我們先補充一個知識點——spring boot默認容器。從創(chuàng)建容器的源碼我們可以看出,在不指定容器類別的情況下,spring boot默認為我們創(chuàng)建的容器是AnnotationConfigServletWebServerApplicationContext(在此之前,我一直以為它走的是default那塊的代碼,debug之后發(fā)現(xiàn)我理解錯了),這個默認容器本身是繼承了ServletWebServerApplicationContext,所以說默認情況下,spring boot為我們創(chuàng)建的是servlet容器:


好了,默認容器的相關(guān)知識點我們先補充這么多,下面我們開始beanDefinitionNames的相關(guān)內(nèi)容分享。
首先,我們先介紹下beanDefinitionNames。從上面的debug截圖中我們其實可以看出來一些信息,beanDefinitionNames其實就是存放spring boot中bean的名字的,通過這個名字我們就可以從spring boot的容器中拿出我們bean的實例:

這也就是說,beanDefinitionNames就是spring boot中IOC容器的名單,通過這個名單我們可以找到容器中的每一個類。
關(guān)于beanDefinitionNames我們暫時就先說這么多,等后面分析BeanFactory的時候我們到時候再來補充。下面我們來看下面這張時序圖:

時序圖svg原圖地址如下:
https://gitee.com/sysker/picBed/raw/master/%E5%AE%B9%E5%99%A8%E5%88%B7%E6%96%B0%E5%90%AF%E5%8A%A8%E6%97%B6%E5%BA%8F%E5%9B%BE.svg
這張時序圖比較清楚地展示了spring boot初始化beanFactory的beanDefinitionNames的過程(beanDefinitionMap的初始化也是如此),但關(guān)于這張時序圖我感覺我能說的很少,雖然調(diào)用過程很清晰,但我目前還沒有梳理清楚各個方法的作用(初始化過程所起的作用),因為每一個方法除了我這里羅列的方法調(diào)用外,還有很多其他的操作,而且由于時間關(guān)系,今天也沒有時間梳理了,目前的計劃是明天把這塊的內(nèi)容補上,然后盡可能再多擴充一些新的知識。
總結(jié)
實話說,spring boot的源碼是真的難啃,從我自己的感覺,以及產(chǎn)出成果來說,確實是太難了
,不僅進度慢,難出成果,而且出來的東西也確實沒有以前分享demo或者其他內(nèi)容那么順暢,現(xiàn)在的感覺就像是在亂石堆里挖井,挖半天下不去,自己還累的夠嗆
,但是把,萬事開頭難,等所有內(nèi)容都梳理的七七八八了,我相信一切都會變的順暢起來的,所以接著啃唄
!
