spring-boot啟動過程實例化補充——關于@Bean

前言
上一次我們在分析spring boot啟動過程實例化方式的時候,關于工廠方法沒有做過多說明,一方面是我確實當時不太清楚,另一方面在spring boot的啟動流程中,我們并沒有找到相關代碼,所以最后就一筆帶過了。
由于最近這兩天把spring boot之前提出的示例demo已經分享完了,最近也正苦于沒有學習目標,因此呢,今天我們就來詳細看下spring boot的工廠實例化方式。
我們今天不在從啟動流程入手,我們換個思路,直接從@Bean注解入手,看下@Bean注解的方法到底是如何被處理的,以及它是何時被處理的。
@Bean注解
首先我搜索了全局有用到Bean.class的地方,找到以下結果:

總共找到10條記錄,其中前兩條和我們昨天分享的條件配置有關,主要是判斷方法是否存在@Bean注解,但是這里并不進行實例化操作,所以我們這里就不深入研究了;
第三行、第四行是獲取所有包含@Bean注解的方法的元數據,但是由于這個類是和異常報告相關的(NoSuchBeanDefinitionFailureAnalyzer,從名字可以看出來是個失敗分析器,找不到bean的定義信息時觸發(fā)),所以我們也不做過多說明。不過從調用的方法名來看,這個方法的作用是獲取所有的beanMethod:
第五行是判斷某個方法是否包含@Bean注解:

第六行是獲取注解的屬性,并從屬性中拿到name屬性,這個屬性最后會變成我們的beanName

第七行是從方法的元數據中獲取@Bean注解的屬性信息,然后將這些屬性信息賦值給bean的定義信息。這個方法很長,信息量也很多,不僅包括了工廠方法的設置,還包括autowire、initMethod、destroyMethod等信息的配置。

然后沿著這個方法我最后進入了refresh方法中,也就是說其實在refresh方法中會調用我們上面這個方法,下面是它的調用流程:

看著這個方法,看著有點眼熟,但是感覺我上次好像沒有講到,然后我又回去翻了下上次源碼分享的內容,最終確認這塊的內容當時確實沒有講到,當時并沒有將這么細。
總體來說,這塊的核心代碼就是處理bean的定義信息,處理完成后,通過@Bean注解配置的bean的定義信息就會被注冊到容器中,然后會在后期實例化的時候,調用bean的工廠方法進行實例化,這種方式就是我們當時沒有展開講的工廠實例方式,這種方式在spring boot中也是廣泛存在的,當然關于這一點我也是今天才知道的。
測試
下面我們通過一個@Bean配置實例來看下。首先是我們通過@Bean注解配置的一個過濾器:

然后在一個偶然情況下,我找到了通過工廠方法實例化的方式(我到現在都不知道當時咋發(fā)現的,這就是機緣吧),這正是這一發(fā)現,我們才有今天的內容,總之就是很偶然。
這是位于SimpleInstantiationStrategy的一個實例化方法,從名字可以看出來,這個類是一種實例化策略,方法的作用就是根據工廠方法實例化對象,從debug截圖可以看出來,這里的factoryMethod就是我們加了@Bean注解的方法名,beanName默認就是我們的方法名:

關于這個方法的調用流程,我們后面有機會再講,今天確實有點太晚了,我們目前只需要搞清楚工廠方法的基本實例化方式就可以了。
總結
今天我們主要圍繞著@Bean注解,分析了工廠方法實例化bean的方式和基本流程。
從內容上來講,其核心就是BeanFactory相關的bean定義信息的設置和賦值,然后就是工廠實例化方式的演示。由于時間的問題,還有一些內容沒有分析到,但是目前的內容已經可以讓我們比較全面地看到@Bean注解的實例化方式,雖然有一定程度的運氣成分,不過這也算是意外的收獲吧。
好了,今天的內容就先到這里吧,各位小伙伴,晚安吧!
- END -