Spring:循環(huán)依賴

關(guān)于循環(huán)依賴有的同學(xué)寫的很好,貼出來:
https://www.cnblogs.com/tiger-fu/p/8961361.html
https://juejin.cn/post/6844903715602694152#heading-7
https://blog.csdn.net/LeoHan163/article/details/106343857
https://www.cnblogs.com/leeego-123/p/12165278.html

Spring中的循環(huán)依賴:

  • 構(gòu)造器循環(huán)依賴

是否解決:通過構(gòu)造器注入構(gòu)成的循環(huán)依賴,此依賴是無法解決的,只能拋出BeanCurrentlyInCreationException異常表示循環(huán)依賴。

原因:創(chuàng)建A類時,構(gòu)造器需要B類,那將去創(chuàng)建B,在創(chuàng)建B類時又發(fā)現(xiàn)需要C類,則又去創(chuàng)建C,最終在創(chuàng)建C時發(fā)現(xiàn)又需要A,從而形成一個環(huán),沒辦法創(chuàng)建。

實現(xiàn)有循環(huán)依賴時拋出異常:
Spring容器會將每一個正在創(chuàng)建的Bean 標(biāo)識符放在一個“當(dāng)前創(chuàng)建Bean池(singletonsCurrentlyInCreation)”中,Bean標(biāo)識符在創(chuàng)建過程中將一直保持在這個池中。
因此如果在創(chuàng)建Bean過程中發(fā)現(xiàn)自己已經(jīng)在“當(dāng)前創(chuàng)建Bean池”里時將拋出BeanCurrentlyInCreationException異常表示循環(huán)依賴。
而對于創(chuàng)建完畢的Bean將從“當(dāng)前創(chuàng)建Bean池”中清除掉。

  • 屬性注入循環(huán)依賴

prototype模式:有狀態(tài)的bean都使用prototype作用域,無狀態(tài)的一般都使用singleton單例作用域。

是否解決:"prototype"作用域bean,Spring容器無法完成依賴注入。

原因:“prototype”作用域的Bean,Spring容器不進(jìn)行緩存,因此無法提前暴露一個創(chuàng)建中的Bean。

singleton模式

是否解決:是的

單例屬性注入如何解決循環(huán)依賴

本質(zhì)上,是通過將半成品實體(實例化,但還未進(jìn)行屬性注入的實體)存放到map中實現(xiàn)的。

用到的map
1.singletonObjects 單例對象列表, beanName -> bean實例。
2.singletonFactories 單例工廠列表 beanName -> beanFactory。
3.earlySingletonObjects 循環(huán)對象依賴列表,對象在創(chuàng)建之后,進(jìn)行注入過程中,發(fā)現(xiàn)產(chǎn)生了循環(huán)依賴,那么會將對象放入到這個隊列,并且從singletonFactories中移除掉。
4.singletonsCurrentlyInCreation 正在創(chuàng)建的單例名稱隊列。
5.registeredSingletons 已經(jīng)創(chuàng)建成功的單例名稱列表。

假設(shè)A與B相互依賴

實例化A之后,此時:
singletonFactories 包含 A
registeredSingletons 包含A
singletonsCurrentlyInCreation 包含A
singletonObjects 不包含A
earlySingletonObjects 不包含A

發(fā)現(xiàn)A需要注入B,于是實例化B,之后發(fā)現(xiàn)B需要A,于是map中拿到A,此時:
singletonFactories 不包含 A
registeredSingletons 包含A
singletonsCurrentlyInCreation 包含A
singletonObjects 不包含A
earlySingletonObjects 包含A

B獲取了A,實例化、初始化完成,此時:
singletonFactories 不包含B
registeredSingletons 包含B
singletonsCurrentlyInCreation 不包含B
singletonObjects 包含B
earlySingletonObjects 不包含B

A繼續(xù)初始化,由于上面B初始化完成,所以可以獲得B,此時:
singletonFactories 不包含A
registeredSingletons 包含A
singletonsCurrentlyInCreation 不包含A
singletonObjects 包含A
earlySingletonObjects 包含A

主要使用了singletonFactories、earlySingletonObjects來解決循環(huán)依賴的問題。如果不是使用aop的情況下,使用一個map也可以解決循環(huán)依賴的問題。但是如果使用了aop,singletonFactories返回的代理對象每次都是不一樣的,所需需要引入earlySingletonObjects。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容