spring迴圈依賴的解決

2021-09-24 12:49:24 字數 3041 閱讀 2441

當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...