當a類中有b屬性,b類中有a屬性的時候,就會產生迴圈依賴。a在例項化的時候,引用了b,但是b麼有例項化,所以就會先例項化b,這個時候發現b又引用了a,但是a還沒有例項化,所以就造成了迴圈依賴。我們來看看spring是如何解決的
**
public class classa
public classa()
public classb getb()
public void setb(classb b)
}
public class classb
public classb()
public classa geta()
public void seta(classa a)
}
配置
測試類
public static void main(string args)
public void test******load()
測試結果
error creating bean with name 'a' defined in class path resource [beanfactorytest.xml]:
cannot resolvereference to bean 'b' while setting constructor argument;
nested exception is org.springframework.beans.factory.beancreationexception:
error creating bean with name 'b' defined in class path resource [beanfactorytest.xml]:
cannot resolve reference to bean 'a' while setting constructor argument;
nested exception is org.springframework.beans.factory.
從測試的結果中看出,構造器迴圈依賴並沒有解決這個問題。
類不變,改變配置
同樣的測試類,測試結果
六月 17, 2019 2:09:42 下午 org.springframework.beans.factory.xml.xmlbeandefinitionreader loadbeandefinitions
資訊: loading xml bean definitions from class path resource [beanfactorytest.xml]
process finished with exit code 0
這裡沒有報錯資訊,setter方式解決了迴圈依賴的問題,我們來看看是如何解決的。
首先要知道乙個bean的乙個時序圖
在上一文spring bean的例項化中我們看到乙個類
abstractbeanfactory 裡面的dogetbean方法
跟蹤這個getsingleton方法
protected object getsingleton(string beanname, boolean allowearlyreference)
}} }
return (singletonobject != null_object ? singletonobject : null);
}
singletonobjects,earlysingletonobjects,singletonfactories這3個map作為**快取
這裡的邏輯就是先找singletonobjects中是否存在bean
如果不存在,然後在找earlysingletonobjects中是否存在
如果還是不存在,在singletonfactories中找到對應的工廠類,然後在用工廠類來例項化,例項化後放入earlysingletonobjects,下次查詢就直接在earlysingletonobjects中能找到了。
根據時序圖,由於單例工廠在屬性引用前就已經產生了,所以在這裡可以直接用singletonfactories來建立對應的例項,例項肯能還不完整,單起碼可以先引用起來。
修改配置檔案
測試結果
error creating bean with name 'a' defined in class path resource [beanfactorytest.xml]:
cannot resolvereference to bean 'b' while setting constructor argument;
nested exception is org.springframework.beans.factory.beancreationexception:
error creating bean with name 'b' defined in class path resource [beanfactorytest.xml]:
cannot resolve reference to bean 'a' while setting constructor argument;
nested exception is org.springframework.beans.factory.
依然會有迴圈依賴的報錯
對於「prototype」作用域的bean,特性就是在每次獲取例項的時候都會新建乙個例項,這樣對於例項就不存在快取的情況,也就不能像單例那樣通過**快取在解決迴圈依賴了。
spring解決迴圈依賴
或者原型 prototype 的場景是不支援迴圈依賴的,丟擲異常。基於構造器的迴圈依賴,是不存在的。那麼預設單例的屬性注入場景,spring是如何支援迴圈依賴的?首先,spring內部維護了三個map,也就是我們通常說的 快取。在spring的defaultsingletonbeanregistry...
spring解決迴圈依賴
之前面試有被問到過,面試官很調皮,我擅長的點沒有問,然後抽了乙個點讓我回答,這個點考察了原始碼的理解,當時只是大概記得是提前暴露,但是細節答得有些粗糙,特補充一下,protected object getsingleton string beanname,boolean allowearlyrefe...
Spring解決迴圈依賴 筆記
參考 spring內部維護了三個map,也就是我們通常說的 快取,位置在defaultsingletonbeanregistry private final mapsingletonobjects new concurrenthashmap 256 private final map singlet...