spring循環引用(bean的循環依賴)解決方案


使用三級緩存來解決循環依賴問題,                      注意:只能解決set方式的依賴注入,構造器方式的不行

一級緩存:singletonObjects,單例對象池,存放完整的SpringBean,也就是走完了整個bean創建生命周期過程。

二級緩存:earlySingletonObjects,早期單例對象。起到復用的作用,多個類都有循環引用該類,那么直接取出來就行。

三級緩存:singletonFactories,單例工廠對象。起到創建代理對象的作用,比如AOP等增強,將實例對象封裝增強后返回

 

我們使用案例說明一下,假如A類依賴B對象, B依賴A對象

具體步驟如下:

1.A依賴B,B依賴A,容器將所有beanName循環出來依次加載bean

2.先實例化A,默認允許開啟循環依賴,封裝A對象單例工廠對象放入三級緩存中

3.設置A屬性值(屬性注入),發現依賴B對象,先從一級緩存緩存查找,沒有的話去二級緩存查找,沒有的話最后從三級緩存查找。 

4.最終未發現B類對一個的實例,還沒有被加載,然后先去加載實例化B對象,並且封裝B對象對應單例工廠對象,放入三級緩存。

5.設置B屬性值(屬性注入),發現依賴A對象,先從一級緩存緩存查找,沒有的話去二級緩存查找,沒有的話最后從三級緩存查找。

6.找到剛才放入三級緩存中的A對象封裝的單例工廠對象,然后調用擴展方法,再創建A類的代理對象放入二級緩存中返回。

7.此時B對象屬性裝配完畢,B對象正常創建放入一級緩存,刪除三級緩存對應單例工廠對象。

8.此時返回剛才創建的B對象給A對象里面對應賦值。

9.此時A屬性裝配完畢,將生成的A對象的代理對象賦值給A對象后,放入一級緩存中,刪除二級緩存中對應對象。

 

那使用兩級緩存不行嗎,為什么一定要用到三級緩存呢?

其實代碼實現上完全可以的,但是考慮到設計模式上一級緩存中都是跑完全流程后完整的對象,

如果直接將三級緩存中生產的不完整對象放入一級緩存,違背了單一職責原則,而且也不好維護,更失去了擴展的功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM