怎樣理解SpringBean生命周期

怎樣理解Spring Bean生命周期,針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

晉安網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,晉安網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為晉安成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請找那個(gè)售后服務(wù)好的晉安做網(wǎng)站的公司定做!

在網(wǎng)上已經(jīng)有跟多Bean的生命周期的博客,但是很多都是基于比較老的版本了,最近把整個(gè)流程化成了一個(gè)流程圖。待會兒使用流程圖,說明以及代碼的形式來說明整個(gè)聲明周期的流程。注意因?yàn)榇a比較多,這里的流程圖只畫出了大概的流程,具體的可以深入代碼。

一、獲取Bean

怎樣理解Spring Bean生命周期 

第一階段獲取Bean

這里的流程圖的入口在 AbstractBeanFactory類的 doGetBean方法,這里可以配合前面的 getBean方法分析文章進(jìn)行閱讀。主要流程就是

1、先處理Bean 的名稱,因?yàn)槿绻浴?amp;”開頭的Bean名稱表示獲取的是對應(yīng)的FactoryBean對象;

2、從緩存中獲取單例Bean,有則進(jìn)一步判斷這個(gè)Bean是不是在創(chuàng)建中,如果是的就等待創(chuàng)建完畢,否則直接返回這個(gè)Bean對象

3、如果不存在單例Bean緩存,則先進(jìn)行循環(huán)依賴的解析

4、解析完畢之后先獲取父類BeanFactory,獲取到了則調(diào)用父類的getBean方法,不存在則先合并然后創(chuàng)建Bean

二、創(chuàng)建Bean

2.1 創(chuàng)建Bean之前

怎樣理解Spring Bean生命周期

在真正創(chuàng)建Bean之前邏輯

這個(gè)流程圖對應(yīng)的代碼在 AbstractAutowireCapableBeanFactory類的 createBean方法中。

1、這里會先獲取 RootBeanDefinition對象中的Class對象并確保已經(jīng)關(guān)聯(lián)了要?jiǎng)?chuàng)建的Bean的Class 。

2、這里會檢查3個(gè)條件

(1)Bean的屬性中的 beforeInstantiationResolved字段是否為true,默認(rèn)是false。

(2)Bean是原生的Bean

(3)Bean的 hasInstantiationAwareBeanPostProcessors屬性為true,這個(gè)屬性在Spring準(zhǔn)備刷新容器錢轉(zhuǎn)杯BeanPostProcessors的時(shí)候會設(shè)置,如果當(dāng)前Bean實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor則這個(gè)就會是true。

當(dāng)三個(gè)條件都存在的時(shí)候,就會調(diào)用實(shí)現(xiàn)的 InstantiationAwareBeanPostProcessor接口的 postProcessBeforeInstantiation方法,然后獲取返回的Bean,如果返回的Bean不是null還會調(diào)用實(shí)現(xiàn)的 BeanPostProcessor接口的 postProcessAfterInitialization方法,這里用代碼說明:

怎樣理解Spring Bean生命周期 3、如果上面3個(gè)條件其中一個(gè)不滿足就不會調(diào)用實(shí)現(xiàn)的方法。默認(rèn)這里都不會調(diào)用的這些 BeanPostProcessors的實(shí)現(xiàn)方法。然后繼續(xù)執(zhí)行后面的 doCreateBean方法。

2.1 真正的創(chuàng)建Bean,doCreateBean

怎樣理解Spring Bean生命周期

doCreateBean方法邏輯

這個(gè)代碼的實(shí)現(xiàn)還是在 AbstractAutowireCapableBeanFactory方法中。流程是

1、先檢查 instanceWrapper變量是不是null,這里一般是null,除非當(dāng)前正在創(chuàng)建的Bean在 factoryBeanInstanceCache中存在這個(gè)是保存還沒創(chuàng)建完成的FactoryBean的集合。

2、調(diào)用createBeanInstance方法實(shí)例化Bean,這個(gè)方法在后面會講解

3、如果當(dāng)前 RootBeanDefinition對象還沒有調(diào)用過實(shí)現(xiàn)了的 MergedBeanDefinitionPostProcessor接口的方法,則會進(jìn)行調(diào)用 。

4、 當(dāng)滿足以下三點(diǎn)(1)是單例Bean(2)嘗試解析bean之間的循環(huán)引用(3)bean目前正在創(chuàng)建中則會進(jìn)一步檢查是否實(shí)現(xiàn)了 SmartInstantiationAwareBeanPostProcessor接口如果實(shí)現(xiàn)了則調(diào)用是實(shí)現(xiàn)的 getEarlyBeanReference方法

5、 調(diào)用 populateBean方法進(jìn)行屬性填充,這里后面會講解

6、 調(diào)用 initializeBean方法對Bean進(jìn)行初始化,這里后面會講解

2.1.1 實(shí)例化Bean,createBeanInstance

怎樣理解Spring Bean生命周期

實(shí)例化Bean

這里的邏輯稍微有一點(diǎn)復(fù)雜,這個(gè)流程圖已經(jīng)是簡化過后的了。簡要根據(jù)代碼說明一下流程:

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

1、先檢查Class是否已經(jīng)關(guān)聯(lián)了,并且對應(yīng)的修飾符是否是public的

2、如果用戶定義了Bean實(shí)例化的函數(shù),則調(diào)用并返回

3、如果當(dāng)前Bean實(shí)現(xiàn)了 FactoryBean接口則調(diào)用對應(yīng)的 FactoryBean接口的 getObject方法

4、根據(jù)getBean時(shí)候是否傳入構(gòu)造參數(shù)進(jìn)行處理

4.1 如果沒有傳入構(gòu)造參數(shù),則檢查是否存在已經(jīng)緩存的無參構(gòu)造器,有則使用構(gòu)造器直接創(chuàng)建,沒有就會調(diào)用 instantiateBean方法先獲取實(shí)例化的策略默認(rèn)是 CglibSubclassingInstantiationStrategy,然后實(shí)例化Bean。最后返回

4.2 如果傳入了構(gòu)造參數(shù),則會先檢查是否實(shí)現(xiàn)了 SmartInstantiationAwareBeanPostProcessor接口,如果實(shí)現(xiàn)了會調(diào)用 determineCandidateConstructors獲取返回的候選構(gòu)造器。

4.3 檢查4個(gè)條件是否滿足一個(gè)

(1)構(gòu)造器不為null,

(2)從RootBeanDefinition中獲取到的關(guān)聯(lián)的注入方式是構(gòu)造器注入(沒有構(gòu)造參數(shù)就是setter注入,有則是構(gòu)造器注入)

(3)含有構(gòu)造參數(shù)

(4)getBean方法傳入構(gòu)造參數(shù)不是空

滿足其中一個(gè)則會調(diào)用返回的候選構(gòu)造器實(shí)例化Bean并返回,如果都不滿足,則會根據(jù)構(gòu)造參數(shù)選擇合適的有參構(gòu)造器然后實(shí)例化Bean并返回

5、如果上面都沒有合適的構(gòu)造器,則直接使用無參構(gòu)造器創(chuàng)建并返回Bean。

2.1.2 填充Bean,populateBean

怎樣理解Spring Bean生命周期

填充Bean

這里還是根據(jù)代碼來說一下流程

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

1、檢查當(dāng)前Bean是否實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor的 postProcessAfterInstantiation方法則調(diào)用,并結(jié)束Bean的填充。2、將按照類型跟按照名稱注入的Bean分開,如果注入的Bean還沒有實(shí)例化的這里會實(shí)例化,然后放到 PropertyValues對象中。3、如果實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor類的 postProcessProperties則調(diào)用這個(gè)方法并獲取返回值,如果返回值是null,則有可能是實(shí)現(xiàn)了過期的 postProcessPropertyValues方法,這里需要進(jìn)一步調(diào)用 postProcessPropertyValues方法4、進(jìn)行參數(shù)填充

2.1.3 初始化Bean,initializeBean

怎樣理解Spring Bean生命周期

初始化Bean

同時(shí)這里根據(jù)代碼跟流程圖來說明

1、如果Bean實(shí)現(xiàn)了 BeanNameAware, BeanClassLoaderAware, BeanFactoryAware則調(diào)用對應(yīng)實(shí)現(xiàn)的方法 。

2、Bean不為null并且bean不是合成的,如果實(shí)現(xiàn)了 BeanPostProcessor的 postProcessBeforeInitialization則會調(diào)用實(shí)現(xiàn)的 postProcessBeforeInitialization方法。在 ApplicationContextAwareProcessor類中實(shí)現(xiàn)了 postProcessBeforeInitialization方法。而這個(gè)類會在Spring刷新容器準(zhǔn)備 beanFactory的時(shí)候會加進(jìn)去,這里就會被調(diào)用,而調(diào)用里面會檢查Bean是不是 EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware的實(shí)現(xiàn)類。這里就會調(diào)用對應(yīng)的實(shí)現(xiàn)方法。代碼如下

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

1、實(shí)例化Bean然后,檢查是否實(shí)現(xiàn)了 InitializingBean的 afterPropertiesSet方法,如果實(shí)現(xiàn)了就會調(diào)用

2、Bean不為null并且bean不是合成的,如果實(shí)現(xiàn)了 BeanPostProcessor的 postProcessBeforeInitialization則會調(diào)用實(shí)現(xiàn)的 postProcessAfterInitialization方法。

到此創(chuàng)建Bean 的流程就沒了,剩下的就是容器銷毀的時(shí)候的了

三、destory方法跟銷毀Bean

Bean在創(chuàng)建完畢之后會檢查用戶是否指定了 destroyMethodName以及是否實(shí)現(xiàn)了 DestructionAwareBeanPostProcessor接口的 requiresDestruction方法,如果指定了會記錄下來保存在 DisposableBeanAdapter對象中并保存在bean的 disposableBeans屬性中。代碼在 AbstractBeanFactory的 registerDisposableBeanIfNecessary中

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

在銷毀Bean的時(shí)候最后都會調(diào)用 AbstractAutowireCapableBeanFactory的 destroyBean方法。

怎樣理解Spring Bean生命周期

這里是創(chuàng)建一個(gè) DisposableBeanAdapter對象,這個(gè)對象實(shí)現(xiàn)了Runnable接口,在實(shí)現(xiàn)的 run方法中會調(diào)用實(shí)現(xiàn)的 DisposableBean接口的 destroy方法。并且在創(chuàng)建 DisposableBeanAdapter對象的時(shí)候會根據(jù)傳入的bean是否實(shí)現(xiàn)了 DisposableBean接口來設(shè)置 invokeDisposableBean變量,這個(gè)變量表實(shí)有沒有實(shí)現(xiàn) DisposableBean接口

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

怎樣理解Spring Bean生命周期

四、總結(jié)

最后來一個(gè)大的流程

怎樣理解Spring Bean生命周期

實(shí)例化前的準(zhǔn)備階段

怎樣理解Spring Bean生命周期

實(shí)例化前

怎樣理解Spring Bean生命周期

實(shí)例化后

怎樣理解Spring Bean生命周期

初始化前

怎樣理解Spring Bean生命周期

關(guān)于怎樣理解Spring Bean生命周期問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

文章題目:怎樣理解SpringBean生命周期
地址分享:http://muchs.cn/article4/johjoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站微信小程序、網(wǎng)頁設(shè)計(jì)公司、App開發(fā)、企業(yè)建站、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司