Spring迴圈依賴 原始碼上分析

2021-10-05 18:56:03 字數 2603 閱讀 3277

一、spring bean 的建立 四個階段

二、defaultsingletonbeanregistry 三個主要不同階段bean的map

今天所要主要關注是 例項化 instantiation(createbeaninstance) 和

屬性賦值 populate (populatebean) 量階段

在spring的defaultsingletonbeanregistry類中,類上方掛著這三個map:

1.singletonobjects:存放初始化好的bean

2.earlysingletonobjects:對映bean的早期引用,也就是說在這個map裡的bean不是完整的,

剛剛完成例項化 階段的bean。

3.singletonfactories:對映建立bean的原始工廠。

三、具體流程

1、先假設spring 初始化中有定義這兩個類

@component

public class a

@component

public class b

2、假如先初始化a,我們從defaultsingletonbeanregistry ->getsingleton 作為入口進行分析

這裡有引數需要特別關注:

issingletoncurrentlyincreation()判斷當前單例bean是否正在建立中,也就是沒有初始化完成(比如a的構造器依賴了b物件所以得先去建立b物件, 或則在a的populatebean過程中依賴了b物件,得先去建立b物件,這時的a就是處於建立中的狀態。)

singletonscurrentlyincreation 這個set 是當前正在建立的bean的set集合

1、defaultsingletonbeanregistry ->getsingleton 中獲取bean的時候

public object getsingleton(string beanname, objectfactory<?> singletonfactory)

if (this.logger.isdebugenabled())

//這個方法需要特別關注,這個方法裡面會執行這行引數

這個新增到singletonscurrentlyincreation 會作為後面的重要判斷

this.beforesingletoncreation(beanname);

boolean newsingleton = false;

boolean recordsuppressedexceptions = this.suppressedexceptions == null;

if (recordsuppressedexceptions)

try

if (newsingleton)

}return singletonobject;

}}

2、在上一段** singletonfactory.getobject(); 會呼叫abstractautowirecapablebeanfactory 類 -> docreatebean 方法

abstractautowirecapablebeanfactory 這個類是defaultsingletonbeanregistry 的子類

protected object docreatebean(string beanname, rootbeandefinition mbd, @nullable object args) throws beancreationexception 

//這一步就是將beanname 放到singletonfactories 最開始的singletonfactories中

this.addsingletonfactory(beanname, () -> );

}object exposedobject = bean;

try catch (throwable var18)

。。。。(省略部分**)

。。。。(省略部分**)

if (continuewithpropertypopulation)

//2 為按型別注入

if (mbd.getresolvedautowiremode() == 2)

pvs = newpvs;

}。。。。(省略部分**)

在上面的注入過程中由於a依賴b,同樣進行上面的相同的操作,在通過b獲取a的時候。

這個時候從singletonfactories移入earlysingletonobjects 中。此時b也獲取到a第一次存在

singletonfactories 的中這個對映,a已經被注入b之中了。當b完成初始化,同樣a繼續完成

populatebean 方法,完成初始化。

protected object getsingleton(string beanname, boolean allowearlyreference) }}

}return singletonobject;

}

如果話總結一下就是,物件a例項化之後都放到乙個暫存區,然後繼續進行屬性配置。當a的成員b同樣依賴a的時候,b可以直接從暫存區取到處於例項化狀態的a 完成b的初始化。a再用b完成a的初始化。

Spring迴圈依賴原始碼Debug

首先我們要搞清楚兩個概念 例項化 初始化 例項化 堆記憶體中申請一塊記憶體空間,類似租賃好房子,自己的家具東西還沒有搬家進去 初始化屬性填充 完成屬性的各種賦值,類似裝修 家電家具進場 快取 四大方法 快取 第一層singletonobjects存放的是已經初始化好了的bean。第二層earlysi...

Spring 解決迴圈依賴原始碼分析

迴圈依賴就是n個類之間迴圈巢狀引用,如a依賴b,b又依賴a,你中有我,我中有你。例項化a時發現需要b屬性,於是去例項化b,發現需要a屬性。如果spring不對這種迴圈依賴進行處理程式就會無限執行,導致記憶體溢位 系統崩潰。迴圈依賴又分為構造器迴圈依賴和屬性迴圈依賴,由於spring不支援構造器迴圈依...

Spring迴圈依賴解決原始碼解析

相關方法 1 spring無法解決構造方法注入引起的迴圈依賴問題 2 spring無法解決多例物件的迴圈依賴問題,因為多例物件是不進行快取的 第一級快取 快取已經完成了例項化和屬性設定的單例物件 單例物件快取 private final map singletonobjects newconcurr...