Spring:循環依賴

關于循環依賴有的同學寫的很好,貼出來:
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中的循環依賴:

  • 構造器循環依賴

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

原因:創建A類時,構造器需要B類,那將去創建B,在創建B類時又發現需要C類,則又去創建C,最終在創建C時發現又需要A,從而形成一個環,沒辦法創建。

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

  • 屬性注入循環依賴

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

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

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

singleton模式

是否解決:是的

單例屬性注入如何解決循環依賴

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

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

假設A與B相互依賴

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

發現A需要注入B,于是實例化B,之后發現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繼續初始化,由于上面B初始化完成,所以可以獲得B,此時:
singletonFactories 不包含A
registeredSingletons 包含A
singletonsCurrentlyInCreation 不包含A
singletonObjects 包含A
earlySingletonObjects 包含A

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

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容