1.什么是循壞依賴
?即循環(huán)引用迈窟,兩個或多個bean相互引用,最終形成一個環(huán)挎塌。如圖:
2.什么是循環(huán)調(diào)用
?循環(huán)調(diào)用是方法之間的環(huán)調(diào)用。循環(huán)調(diào)用無法解決内边,除非有終結(jié)條件榴都,否則就是死循環(huán),最終導(dǎo)致內(nèi)存溢出錯誤漠其。
3.構(gòu)造器循環(huán)依賴
?3.1 循環(huán)依賴過程
定義類依賴:
Class A{
private B b;
A(B b){
this.b = b;
}
}
Class B{
private C c;
B(C c){
this.c = c;
}
}
Class C{
private A a;
C(A a){
this.a = a;
}
}
JVM創(chuàng)建對象過程 如下圖所示:
3.2 Spring解決構(gòu)造器循環(huán)依賴
?無法解決通過構(gòu)造器注入構(gòu)成的循環(huán)依賴嘴高,只能拋出BeanCurrentylyInCreationException異常表示循環(huán)依賴。
?Spring容器將每一個正在創(chuàng)建的bean標(biāo)識符放在一個“當(dāng)前創(chuàng)建bean池”中和屎,bean表示符在創(chuàng)建過程中將一直保持在這個池中拴驮,因此,如果在創(chuàng)建bean過程中發(fā)現(xiàn)自己已經(jīng)在“當(dāng)前創(chuàng)建bean池”中柴信,將拋出BeanCurrentylyInCreationException異常套啤,表示循環(huán)依賴;對于創(chuàng)建完畢的bean随常,將從“當(dāng)前創(chuàng)建bean池”中清除掉潜沦。
4.setter循環(huán)依賴
?通過Spring容器提前暴露剛完成構(gòu)造器注入但未完成其他步驟(如setter注入)的bean來完成的。通過提前暴露一個單例工廠方法绪氛,從而使其他bean能夠引用到該bean唆鸡。
?注:只能解決單例作用域的bean循環(huán)依賴。
?具體步驟:
?(1)Spring容器創(chuàng)建單例 a bean枣察,首先根據(jù)無參構(gòu)造器創(chuàng)建bean争占,并暴露一個“ObjectFactory”,用于返回一個提前暴露一個創(chuàng)建中的bean序目,并將 “a”標(biāo)識符放到“當(dāng)前創(chuàng)建bean池”臂痕,然后進(jìn)行setter注入b;
?(2)Spring容器創(chuàng)建單例 b bean,首先根據(jù)無參構(gòu)造器創(chuàng)建bean猿涨,并暴露一個“ObjectFactory”刻蟹,用于返回一個提前暴露一個創(chuàng)建中的bean,并將 “b”標(biāo)識符放到“當(dāng)前創(chuàng)建bean池”嘿辟,然后進(jìn)行setter注入c;
?(3)Spring容器創(chuàng)建單例 c bean舆瘪,首先根據(jù)無參構(gòu)造器創(chuàng)建bean片效,并暴露一個“ObjectFactory”,用于返回一個提前暴露一個創(chuàng)建中的bean英古,并將 “c”標(biāo)識符放到“當(dāng)前創(chuàng)建bean池”淀衣,然后進(jìn)行setter注入a;進(jìn)行注入"a"時,由于提前暴露了“ObjectFactory”工廠召调,從而使用它返回提前暴露一個創(chuàng)建中的bean膨桥。
?(4)最后在依賴注入“b”和“a”,完成setter注入唠叛。
另附個人覺得講的非常明白的一篇博客:
https://blog.csdn.net/qq_36381855/article/details/79752689
注:參考《Spring深度解析》