spring-boot源碼分析之BeanFactory · 叁

前言
今天我們繼續(xù)研究BeanFactory,不過(guò)今天分享的內(nèi)容有點(diǎn)零散,主要包括三個(gè)方面的內(nèi)容,一個(gè)是ApplicationContextInitializer的初始化,這個(gè)嚴(yán)格來(lái)說(shuō)和BeanFactory沒(méi)什么關(guān)系,但是源碼也分析了,所以這里提一下;另一個(gè)是ignoredDependencyInterfaces,這個(gè)是BeanFactory的一個(gè)核心屬性,用于屏蔽我們不需要進(jìn)行依賴(lài)檢查和自動(dòng)注入的接口;最后一個(gè)是beanDefinitionMap,這一次我們找到了它最開(kāi)始初始化的代碼,所以這里一起分享下。
BeanFactory初始化過(guò)程
ApplicationContextInitializer初始化
下面是ApplicationContextInitializer的初始化操作,ApplicationContextInitializer是spring boot提供的一套初始化機(jī)制,它的initialize方法在spring boot容器刷新前執(zhí)行,通常被用來(lái)進(jìn)行配置文件初始化,我們也可以自己定義自己的ApplicationContextInitializer,后面我們可以做一期demo示例。
ApplicationContextInitializer的初始化操作是在 prepareContext方法中被執(zhí)行的,默認(rèn)情況下,會(huì)有7個(gè) ApplicationContextInitializer被執(zhí)行

下面是第一個(gè)ApplicationContextInitializer的方法源碼其他類(lèi)似,需要注意的是ApplicationContextInitializer本身是順序的,而且方法內(nèi)部也有排序操作:

在第二個(gè)ApplicationContextInitializer初始化方法內(nèi)容,它往容器中注冊(cè)了BeanFactory的后置處理器

回到容器初始化開(kāi)始的地方
根據(jù)下面的截圖,我們可以看出來(lái),beanFactory其實(shí)在容器創(chuàng)建完成后,已經(jīng)完成了一部分初始化操作,所以想要搞清楚beanFactroy的初始,必須要回到beanFactory初始化的地方。

發(fā)現(xiàn)ignoredDependencyInterfaces
ignoredDependencyInterfaces是BeanFactory的一個(gè)核心屬性,用于屏蔽我們不需要進(jìn)行依賴(lài)檢查和自動(dòng)注入的接口,下面是BeanFactory初始化ignoredDependencyInterfaces的代碼,這段代碼也是在創(chuàng)建容器的時(shí)候被執(zhí)行的。

ignoredDependencyInterfaces存放的是需要忽略的依賴(lài)接口,默認(rèn)情況下只會(huì)加入BeanFactoryAware的接口,根據(jù)官方解釋?zhuā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);">ignoredDependencyInterfaces中的接口,會(huì)忽略依賴(lài)檢查,并且不會(huì)被autowire

找到beanDefinitionMap初始化開(kāi)始的地方
下面是beanDefinitionMap最開(kāi)始初始化的代碼,我們可以看到,在執(zhí)行完registry.registerBeanSefinition方法之后,第一個(gè)bean的definition信息被成功注冊(cè)。
下面是registerAnnotationConfigProcessors方法的完整截圖:




這個(gè)方法在AnnotationConfigUtils這個(gè)類(lèi)中,它是在實(shí)例化AnnotationConfigServletWebServerApplicationContext的reader屬性的時(shí)候被執(zhí)行的。


這個(gè)方法的作用是注冊(cè)給定的注解后置處理器,從包名上我們可以看出來(lái),這五個(gè)類(lèi)有兩個(gè)是和事件監(jiān)聽(tīng)器相關(guān)的,有三個(gè)是和注解相關(guān)的,其中還有一個(gè)類(lèi)沒(méi)有被注入,是和jpa相關(guān)的組件,應(yīng)該和我們沒(méi)有引入jpa的依賴(lài)和配置有關(guān)系。關(guān)于beanDefinitionMap我們暫時(shí)就先說(shuō)這么多,至于這五個(gè)最先被注冊(cè)的元老級(jí)類(lèi),我們后面再來(lái)詳細(xì)了解。
總結(jié)
spring boot的源碼真的太上頭了
,這些內(nèi)容本來(lái)是中午要輸出的,但是由于早上沒(méi)有太多進(jìn)展,最后連圖都沒(méi)畫(huà)好,然后中午也沒(méi)有理出內(nèi)容,一直等到下班回到家
,才開(kāi)始真正干活,所以今天的絕大多數(shù)內(nèi)容都是晚上回到家才搞出來(lái)的。嚴(yán)格來(lái)說(shuō),最近這幾天都是如此,但是經(jīng)過(guò)我最近這段時(shí)間的梳理和硬啃,現(xiàn)在感覺(jué)多少有點(diǎn)眉目了,自我感覺(jué)關(guān)于run方法我已經(jīng)梳理完40%~50%的內(nèi)容,剩下reflush方法大概能占到30%的內(nèi)容,事件監(jiān)聽(tīng)相關(guān)內(nèi)容大概占比20%,反正感覺(jué)慢慢能看見(jiàn)勝利的曙光了
……加油吧,沒(méi)有別的選擇了
~
好了,各位小伙伴晚安
!
