spring如何解決迴圈依賴

2021-10-24 12:18:49 字數 1146 閱讀 3752

1. 構造器注入:無法解決

構造器注入時,a,b都沒有進行初始化物件(構造方法無法執行完成)

2.spring 為了解決單例的迴圈依賴問題,使用了**快取。其中一級快取為單例池(singletonobjects),二級快取為提前**物件(earlysingletonobjects),**快取為提前**物件工廠(singletonfactories)。

假設a,b迴圈依賴,a初始化時發現依賴b,這時就會去找b,b有發現屬性初始化又依賴於a,這是又去找a,spring首先從singletonobjects(一級快取)中嘗試獲取,如果獲取不到並且物件在建立中,則嘗試從earlysingletonobjects(二級快取)中獲取,如果還是獲取不到並且允許從singletonfactories通過getobject獲取,則通過singletonfactory.getobject()(**快取)獲取。如果獲取到了則移除對應的singletonfactory,將singletonobject放入到earlysingletonobjects,其實就是將**快取提公升到二級快取中. 找到a後,b完成初始化,接著完成a的初始化,在b物件中,存的只是a的引用,隨著a初始化完成後整個流程完成。

3.為什麼要使用**快取呢?二級快取能解決迴圈依賴嗎?

如果沒有 aop **,二級快取可以解決問題。

有aop的話,二級快取會出問題:只通過二級快取(earlysingletonobjects)獲取的物件是乙個原始的物件。

以io流舉例,我們一開始都是用的原始位元組流,然後給別人用的也是位元組流,但是,最後,我感覺不方便,我自己悄悄弄了個快取字元流(模擬**物件),我是方便了,但是,別人用的,還是原始的位元組流啊。

你bean不是單例嗎?不能這麼玩吧?

所以,這就是二級快取,不能解決的問題。

4.**快取,怎麼解決這個問題

要解決這個問題,必須在其他bean獲取物件的時候,查詢到最終形態的物件,即**後的物件。

怎麼做到這點呢?

加個**快取,裡面不存具體的bean,裡面存乙個工廠物件。通過工廠物件,是可以拿到最終形態的**後的物件。

裡面的核心方法:

public object getearlybeanreference(object bean, string beanname) throws bean***ception

Spring如何解決迴圈依賴

比如 在a類引入b物件,在b類引入a物件,建立a的時候需要依賴b,建立b的時候需要依賴a,而各自建立物件的時候,其互相依賴的物件還沒有建立完成,就導致各自都無法成功建立物件。這就是迴圈依賴。class aclass b解決迴圈依賴的方法很簡單,如下所示,先例項化a和b,此時都沒初始化,即都沒有對各自...

Spring如何解決迴圈依賴

多個bean之間相互依賴,形成了乙個閉環。比如 a依賴於b b依賴於c c依賴於a 通常來說,如果問spring容器內部如何解決迴圈依賴,一定是指預設的單例bean中,屬性互相引用的場景。也就是說,spring的迴圈依賴,是spring容器注入時候出現的問題。例項化a 將半成品的a放入singlet...

Spring如何解決迴圈依賴的?

假設有兩個例項a,b迴圈依賴。且作用域都是單例,因為spring只支援單例的迴圈依賴。假設掃瞄到了a,呼叫getbean方法,由於是單例,呼叫getsingleton方法,發現三個緩中都沒有a,進入createbeaninstance的流程。此時建立的是能夠建立a的工廠放進了 快取裡面,然後執行po...