BeanFactory是spring的核心,我們都知道可以從BeanFactory中獲取到指定的bean(通過(guò)名字或者Class),同時(shí)我們也會(huì)很好奇,bean是怎么被加載到BeanFactory里面的呢?Spring又給我們留了哪些后門能夠插手這個(gè)加載過(guò)程呢?帶著這些疑問(wèn),我們通過(guò)源碼一步一步來(lái)分析。
首先我們看一下BeanFactory的一個(gè)簡(jiǎn)單的UML圖,并對(duì)其中幾個(gè)進(jìn)行簡(jiǎn)單分析,這樣有助于理解

1、BeanFactory
這是最頂層的接口,它定義了工廠類最核心的方法(可以想想工廠模式,定義一個(gè)獲取產(chǎn)品的接口)

2、HierarchicalBeanFactory
BeanFactory的直接子接口,表示Bean是有繼承關(guān)系的,也就是Bean可能有父Bean

3、ListableBeanFactory
BeanFactory的又一個(gè)直接子接口,表示這些bean可列表化(可以簡(jiǎn)單理解為增加了一些接口,可以根據(jù)不同的條件來(lái)查詢bean或者bean的信息)

4、AutowireCapableBeanFactory
BeanFactory的直接子接口,定義bean的自動(dòng)裝配規(guī)則(bean創(chuàng)建,屬性設(shè)置,依賴注入,各種攔截器等)。

通過(guò)分析這4個(gè)接口,我們能夠猜到BeanFactory創(chuàng)建bean真正的類應(yīng)該是AutowireCapableBeanFactory的子類。
沒(méi)錯(cuò),Spring加載Bean的位置確實(shí)是AutowireCapableBeanFactory的直接子類AbstractAutowireCapableBeanFactory。接下來(lái)我們一步一步來(lái)分析AbstractAutowireCapableBeanFactory的createBean方法。
5、AbstractAutowireCapableBeanFactory
實(shí)現(xiàn)了bean的創(chuàng)建?,F(xiàn)在我們來(lái)分析一下他的創(chuàng)建的過(guò)程。

可以看出此方法并沒(méi)有真正創(chuàng)建Bean,我們接著往下看createBean

從源碼中可以看出此方法定義了bean創(chuàng)建的步驟:
第一步:先確保bean的Class能被解析
第二步:在實(shí)例化bean之前,給了一個(gè)鉤子(InstantiationAwareBeanPostProcessor),允許我們?cè)阢^子中直接返回一個(gè)我們創(chuàng)建的bean或者代理,這樣,Spring就不會(huì)繼續(xù)往下執(zhí)行,也就不會(huì)在創(chuàng)建bean

第三步:調(diào)用doCreateBean,進(jìn)行bean的實(shí)例化,以及后續(xù)加工處理。
接著我們繼續(xù)看doCreateBean方法:



解釋一下主要的創(chuàng)建流程:
第一步:根據(jù)情況實(shí)例化bean
a:如果Bean配置了FactoryMethod,那么使用FactoryMethod進(jìn)行實(shí)例化
b:如果Bean在次之前已經(jīng)解析出了實(shí)例化的構(gòu)造函數(shù)或者FactoryMethod,那么根據(jù)情況使用構(gòu)造函數(shù)或者FactoryMethod進(jìn)行實(shí)例化
c:如果能夠確定是否指定了構(gòu)造函數(shù),那么使用確定的構(gòu)造函數(shù)進(jìn)行實(shí)例化
d:如果都沒(méi)有,那么直接使用默認(rèn)構(gòu)造函數(shù)(即無(wú)參構(gòu)造函數(shù))進(jìn)行實(shí)例化
(真正實(shí)例化bean使用了策略模式,會(huì)根據(jù)bean的信息選擇不同的實(shí)例化策略,后面詳細(xì)介紹)

第二步:Spring又提供了一個(gè)鉤子(MergedBeanDefinitionPostProcessor),這是用于合并bean定義的后處理器。這么說(shuō)肯定一臉懵,完全不知道有什么用。
舉個(gè)例子:我們都知道Bean中可以使用@Autowired注解來(lái)配置另外一個(gè)Bean,Spring解析Autowired注解的時(shí)機(jī)就是此時(shí)此刻,以便下一步進(jìn)行屬性填充(或者說(shuō)注入)
(MergedBeanDefinitionPostProcessor這個(gè)接口對(duì)@Autowired和@Value的支持起到了至關(guān)重要的作用,當(dāng)某個(gè)bean在實(shí)例化后就會(huì)調(diào)到所有的實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口的實(shí)例。)
例如:
CommonAnnotationBeanPostProcessor這個(gè)處理器用來(lái)解析類中使用的@Resource注解AutowiredAnnotationBeanPostProcessor這個(gè)處理器用來(lái)解析類中使用的@Autowired注解
(注意這些處理器只是用來(lái)解析類使用的這些注解,并不會(huì)直接注入對(duì)應(yīng)的值)

第三步:填充bean的屬性、依賴等
這個(gè)過(guò)程也涉及很多流程,但是最終就是Spring會(huì)在這個(gè)步驟中將bean對(duì)應(yīng)的依賴進(jìn)行設(shè)置
第四步:對(duì)bean進(jìn)行初始化
初始化我們不要和前面的實(shí)例化混淆了。初始化指的是當(dāng)我們的bean實(shí)例化之后,有可能需要做一些初始化工作(比如:預(yù)加載數(shù)據(jù))。接下來(lái)我們分析一下Spring對(duì)初始化做了哪些操作。

a、調(diào)用三類Bean的對(duì)應(yīng)方法,他們分別是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,我們分別可以獲得bean的名字、bean的Class加載器、bean的創(chuàng)建工廠。其中BeanFactoryAware是我們常用的,我們的BeanUtil通過(guò)實(shí)現(xiàn)它,然后在其他服務(wù)中可以通過(guò)BeanUtil獲取BeanFactory,從而在程序運(yùn)行中獲取其中的Bean

b、初始化前的鉤子,即:調(diào)用BeanPostProcessor的postProcessBeforeInitialization方法

c、調(diào)用Bean的初始化方法
此處我們要注意:
如果Bean實(shí)現(xiàn)了InitializingBean,那么Spring就會(huì)在此刻調(diào)用它的afterPropertiesSet()方法
如果Bean指定了初始化方法,那么Spring會(huì)調(diào)用這個(gè)方法

d、初始化后的鉤子,即:調(diào)用BeanPostProcessor的postProcessAfterInitialization方法

至此,Spring創(chuàng)建Bean的流程基本結(jié)束。