大家都清楚spring框架實現類ioc,即實現了依賴的自動注入,這是spring的基本功能之一,並且對於迴圈依賴,spring也可以自動注入,但是前提是存在迴圈依賴關係的bean必須是單例的,原型的不可以。
1.什麼是迴圈依賴
簡單來說就是兩個類的相互引用,舉個例子來說,a類定義乙個b類的例項字段,b類也定義乙個a類的例項字段。
class
aclass
b
當載入a或b例項時就會發生,那麼spring是怎麼處理的呢?
2.spring處理迴圈依賴思路
3.偽**模擬實現
定義幾個儲存bean的集合,以及乙個方法。
map
singletonobjects;
//儲存已經完成初始化的單例的map,key是beanname
//下面的定義就是為了解決迴圈依賴
map?>> singletonfactories;
//建立bean的工廠map,objectfactory是個介面,只有乙個方法getobject(),返回bean
mapearlysingletonobjects;
//儲存還未裝配屬性的bean
setsingletonscurrentlyincreation;
//儲存正在建立過程中的bean
object getbean
(string beanname)
//2.如果當前bean正在建立過程中,其實也就是存在迴圈依賴,不然singletonscurrentlyincreation不會包含 beanname
if(singletonscurrentlyincreation.
contatins
(beanname))}
//快取不存在
if(singletonobject==null)
return singletonobject;
}
上面方法大致模擬了spring載入bean的流程,實際的過程要比這複雜的多,靈活的得多,這只是為說明迴圈依賴的解決思路,提取出的部分邏輯。
4.過程分析
以a依賴b,b依賴a為例,按照上面的偽**,分析a載入過程,從getbean(a)開始分析
singletonobjects集合中不存在a的例項a,singletonscurrentlyincreation中也不存「a」,所以會執行a的例項化邏輯,先將「a」加入到singletonscurrentlyincreation集合,表示「a」正在建立過程中。
建立beanname為a的例項
將建立a例項的工廠加入到singletonfactories中,簡單來說,呼叫getobject方法時,就是返回singletonobject
裝配a的屬性
發現引用b的例項,開始呼叫方法getbean(b),與上面的getbean(a)相似
裝配b的屬性
發現引用a的例項,開始呼叫方法getbean(a)
singletonobjects不存在a的例項
a正在建立過程中,singletonscurrentlyincreation包含「a」
earlysingletonobjects不存在a的例項
去工廠中獲取a的例項,其實就是第一次建立a的例項的帶下劃線的singletonobject
singletonobject放在earlysingletonobjects快取
singletonobject不是null,後面的邏輯不執行
b裝配完畢,singletonscurrentlyincreation中移除「b」
將b快取到singletonobjects,singletonfactories移除b的工廠,earlysingletonobjects移除b
初始化b
a裝配完畢,singletonscurrentlyincreation中移除「a」
將a快取到singletonobjects,singletonfactories移除a的工廠,earlysingletonobjects移除a
初始化a
至此a載入完畢,b也載入完畢,也解決了迴圈依賴問題。
以上只是本人學習spring的bean載入過程的學習筆記,理解的不準確的地方歡迎大佬拍磚,如果有幫到您歡迎點讚收藏。
Spring處理迴圈依賴
什麼是迴圈依賴?a類注入b b注入c c注入a 形成了乙個依賴環 直接上spring原始碼 boolean earlysingletonexposure mbd.issingleton this allowcircularreferences issingletoncurrentlyincreati...
Spring原理 二 迴圈依賴原理
component public class x component public class y spring解決迴圈依賴的訣竅就在於singletonfactories這個 快取,x首先完成例項化 呼叫了構造器 並且將自己提前 到singletonfactories中 如果支援迴圈依賴 spri...
spring 迴圈依賴
構造器依賴無法解決,使用 快取解決field屬性依賴。a的屬性依賴b,b的屬性依賴a 建立a,設定依賴屬性b,發現b沒有建立,建立b,設定依賴屬性a,先從一級快取singletonobjects中去獲取。如果獲取到就直接return 如果獲取不到或者物件正在建立中 issingletoncurren...