怎樣理解Spring Bean生命周期,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
晉安網(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)站制作要多少錢(qián),請(qǐng)找那個(gè)售后服務(wù)好的晉安做網(wǎng)站的公司定做!
在網(wǎng)上已經(jīng)有跟多Bean的生命周期的博客,但是很多都是基于比較老的版本了,最近把整個(gè)流程化成了一個(gè)流程圖。待會(huì)兒使用流程圖,說(shuō)明以及代碼的形式來(lái)說(shuō)明整個(gè)聲明周期的流程。注意因?yàn)榇a比較多,這里的流程圖只畫(huà)出了大概的流程,具體的可以深入代碼。
這里的流程圖的入口在 AbstractBeanFactory類(lèi)的 doGetBean方法,這里可以配合前面的 getBean方法分析文章進(jìn)行閱讀。主要流程就是
1、先處理Bean 的名稱(chēng),因?yàn)槿绻浴?amp;”開(kāi)頭的Bean名稱(chēng)表示獲取的是對(duì)應(yīng)的FactoryBean對(duì)象;
2、從緩存中獲取單例Bean,有則進(jìn)一步判斷這個(gè)Bean是不是在創(chuàng)建中,如果是的就等待創(chuàng)建完畢,否則直接返回這個(gè)Bean對(duì)象
3、如果不存在單例Bean緩存,則先進(jìn)行循環(huán)依賴(lài)的解析
4、解析完畢之后先獲取父類(lèi)BeanFactory,獲取到了則調(diào)用父類(lèi)的getBean方法,不存在則先合并然后創(chuàng)建Bean
這個(gè)流程圖對(duì)應(yīng)的代碼在 AbstractAutowireCapableBeanFactory類(lèi)的 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ō)明:
3、如果上面3個(gè)條件其中一個(gè)不滿(mǎn)足就不會(huì)調(diào)用實(shí)現(xiàn)的方法。默認(rèn)這里都不會(huì)調(diào)用的這些 BeanPostProcessors的實(shí)現(xiàn)方法。然后繼續(xù)執(zhí)行后面的 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)滿(mǎn)足以下三點(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ì)講解
這里的邏輯稍微有一點(diǎn)復(fù)雜,這個(gè)流程圖已經(jīng)是簡(jiǎn)化過(guò)后的了。簡(jiǎn)要根據(jù)代碼說(shuō)明一下流程:
1、先檢查Class是否已經(jīng)關(guān)聯(lián)了,并且對(duì)應(yīng)的修飾符是否是public的
2、如果用戶(hù)定義了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è)條件是否滿(mǎn)足一個(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ù)不是空
滿(mǎn)足其中一個(gè)則會(huì)調(diào)用返回的候選構(gòu)造器實(shí)例化Bean并返回,如果都不滿(mǎn)足,則會(huì)根據(jù)構(gòu)造參數(shù)選擇合適的有參構(gòu)造器然后實(shí)例化Bean并返回
5、如果上面都沒(méi)有合適的構(gòu)造器,則直接使用無(wú)參構(gòu)造器創(chuàng)建并返回Bean。
這里還是根據(jù)代碼來(lái)說(shuō)一下流程
1、檢查當(dāng)前Bean是否實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor的 postProcessAfterInstantiation方法則調(diào)用,并結(jié)束B(niǎo)ean的填充。2、將按照類(lèi)型跟按照名稱(chēng)注入的Bean分開(kāi),如果注入的Bean還沒(méi)有實(shí)例化的這里會(huì)實(shí)例化,然后放到 PropertyValues對(duì)象中。3、如果實(shí)現(xiàn)了 InstantiationAwareBeanPostProcessor類(lèi)的 postProcessProperties則調(diào)用這個(gè)方法并獲取返回值,如果返回值是null,則有可能是實(shí)現(xiàn)了過(guò)期的 postProcessPropertyValues方法,這里需要進(jìn)一步調(diào)用 postProcessPropertyValues方法4、進(jìn)行參數(shù)填充
同時(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類(lèi)中實(shí)現(xiàn)了 postProcessBeforeInitialization方法。而這個(gè)類(lèi)會(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)類(lèi)。這里就會(huì)調(diào)用對(duì)應(yīng)的實(shí)現(xiàn)方法。代碼如下
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)了,剩下的就是容器銷(xiāo)毀的時(shí)候的了
Bean在創(chuàng)建完畢之后會(huì)檢查用戶(hù)是否指定了 destroyMethodName以及是否實(shí)現(xiàn)了 DestructionAwareBeanPostProcessor接口的 requiresDestruction方法,如果指定了會(huì)記錄下來(lái)保存在 DisposableBeanAdapter對(duì)象中并保存在bean的 disposableBeans屬性中。代碼在 AbstractBeanFactory的 registerDisposableBeanIfNecessary中
在銷(xiāo)毀Bean的時(shí)候最后都會(huì)調(diào)用 AbstractAutowireCapableBeanFactory的 destroyBean方法。
這里是創(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接口
四、總結(jié)
關(guān)于怎樣理解Spring Bean生命周期問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
文章題目:怎樣理解SpringBean生命周期
地址分享:http://jinyejixie.com/article4/johjoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、微信小程序、網(wǎng)頁(yè)設(shè)計(jì)公司、App開(kāi)發(fā)、企業(yè)建站、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)