什麼是迴圈依賴?
a類注入b
b注入c
c注入a 形成了乙個依賴環
直接上spring原始碼
boolean earlysingletonexposure =
(mbd.
issingleton()
&&this
.allowcircularreferences &&
issingletoncurrentlyincreation
(beanname));
if(earlysingletonexposure)
addsingletonfactory
(beanname,()
->
getearlybeanreference
(beanname, mbd, bean));
}
必須滿足這三個條件
1.bean是單例的
2.允許迴圈依賴(預設為true)
3.存在迴圈依賴的情況(c在依賴a的時候,發現a正在例項化)
issingletoncurrentlyincreation(beanname)原始碼
//private final setsingletonscurrentlyincreation =collections.newsetfrommap(new concurrenthashmap<>(16));
//儲存當前正在建立的bean
this
.singletonscurrentlyincreation.
contains
(beanname)
;
下面看這個方法:addsingletonfactory(beanname, () -> getearlybeanreference(beanname, mbd, bean));(bean在例項化後,屬性填充前,還沒有填充屬性的bean叫原始bean,也就是這裡的earlybean)
看spring是怎麼處理的?
先看getearlybeanreference方法,返回乙個objectfactory
//這裡的第三個引數bean,就是原始bean
protected object getearlybeanreference
(string beanname, rootbeandefinition mbd, object bean)}}
return exposedobject;
protected
void
addsingletonfactory
(string beanname, objectfactory<
?> singletonfactory)}}
//看看這個objectfactory介面的定義
@functionalinte***ce
public
inte***ce
objectfactory
下面看當bean初始化完後有這個邏輯:
需要結合上面的**塊一起看
@nullable
protected object getsingleton
(string beanname,
boolean allowearlyreference)}}
}return singletonobject;
}
看了上面的邏輯,就知道處理邏輯了:
spring檢查到有迴圈依賴,就先將原始bean暴露出去(將a的原始bean暴露出去),提供objectfactory.getobject方法獲取原始bean,這樣c在設定屬性a時,就可以通過a的物件工廠獲取到a的原始bean,這樣c就可以完成建立,c完成了a就可以完成了。因為c的屬性a的位址和後面建立完成的a指向的是同乙個記憶體位址,所有c的屬性a也是完整的。
Spring處理迴圈依賴原理
大家都清楚spring框架實現類ioc,即實現了依賴的自動注入,這是spring的基本功能之一,並且對於迴圈依賴,spring也可以自動注入,但是前提是存在迴圈依賴關係的bean必須是單例的,原型的不可以。1.什麼是迴圈依賴 簡單來說就是兩個類的相互引用,舉個例子來說,a類定義乙個b類的例項字段,b...
spring 迴圈依賴
構造器依賴無法解決,使用 快取解決field屬性依賴。a的屬性依賴b,b的屬性依賴a 建立a,設定依賴屬性b,發現b沒有建立,建立b,設定依賴屬性a,先從一級快取singletonobjects中去獲取。如果獲取到就直接return 如果獲取不到或者物件正在建立中 issingletoncurren...
spring迴圈依賴
關於spring迴圈依賴網上有太多的例子,本文只是簡單的記錄一下。本文預設讀者熟悉spring核心之一控制反轉和依賴注入 在我們的開發過程中,我們基本上對迴圈依賴是無感且不用去考慮如何解決。如上圖中classa使用屬性注入了classb,classb使用屬性注入了classa。如上圖這就是產生了迴圈...