Spring處理迴圈依賴原理

2021-10-17 18:44:55 字數 2114 閱讀 1938

大家都清楚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...