自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

11張流程圖搞定Spring Bean生命周期

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

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

一、獲取Bean

11張流程圖搞定 Spring Bean 生命周期 

第一階段獲取Bean

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

1、先處理Bean 的名稱,因?yàn)槿绻?ldquo;&”開(kāi)頭的Bean名稱表示獲取的是對(duì)應(yīng)的FactoryBean對(duì)象;

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

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

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

二、創(chuàng)建Bean

2.1 創(chuàng)建Bean之前

11張流程圖搞定 Spring Bean 生命周期

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

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

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

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

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

(2)Bean是原生的Bean

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

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

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

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

11張流程圖搞定 Spring Bean 生命周期

doCreateBean方法邏輯

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

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

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

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

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

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

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

2.1.1 實(shí)例化Bean,createBeanInstance

11張流程圖搞定 Spring Bean 生命周期

實(shí)例化Bean

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

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期

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

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

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

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

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

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

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

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

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

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

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

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

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

2.1.2 填充Bean,populateBean

11張流程圖搞定 Spring Bean 生命周期

填充Bean

這里還是根據(jù)代碼來(lái)說(shuō)一下流程

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期 

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

2.1.3 初始化Bean,initializeBean

11張流程圖搞定 Spring Bean 生命周期

初始化Bean

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

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

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

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期

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

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

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

三、destory方法跟銷毀Bean

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

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期

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

11張流程圖搞定 Spring Bean 生命周期

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

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期

11張流程圖搞定 Spring Bean 生命周期

四、總結(jié)

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

11張流程圖搞定 Spring Bean 生命周期

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

11張流程圖搞定 Spring Bean 生命周期

實(shí)例化前

11張流程圖搞定 Spring Bean 生命周期

實(shí)例化后

11張流程圖搞定 Spring Bean 生命周期

初始化前

11張流程圖搞定 Spring Bean 生命周期

 

 

責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)架構(gòu)
相關(guān)推薦

2022-10-19 23:28:55

Spring生命周期Bean

2024-05-28 07:55:31

SpringBean用域

2023-12-28 09:59:37

Spring容器XML

2021-12-08 11:18:21

Spring Bean面試題生命周期

2022-03-14 08:54:42

SpringBean生命周期

2020-09-08 15:14:51

線程 APIs周期

2022-09-05 07:06:59

BeanSpring

2023-10-07 00:05:07

2011-04-19 09:27:25

Spring

2024-03-14 10:47:12

Spring生命周期阿里

2023-10-05 06:01:28

2020-06-10 07:38:30

Spring框架周期

2015-07-08 16:28:23

weak生命周期

2022-04-19 07:20:24

軟件開(kāi)發(fā)安全生命周期SSDLC應(yīng)用安全

2009-06-24 10:47:55

JSF生命周期

2012-06-20 10:29:16

敏捷開(kāi)發(fā)

2013-08-19 17:03:00

.Net生命周期對(duì)象

2021-07-19 05:52:29

網(wǎng)絡(luò)生命周期網(wǎng)絡(luò)框架

2022-08-02 08:00:00

機(jī)器學(xué)習(xí)數(shù)據(jù)框架

2009-06-11 11:28:35

JSF生命周期
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)