深入理解Spring中的循環(huán)依賴
循環(huán)依賴
定義: 循環(huán)依賴就是循環(huán)引用,就是兩個(gè)或多個(gè)Bean相互之間的持有對(duì)方,比方CircularityA引用CircularityB,CircularityB引用CircularityC,CircularityC引用CircularityA。形成一個(gè)環(huán)狀引用關(guān)系。
在使用Spring時(shí),如果主要采用基于構(gòu)造器的依賴注入方式,則可能會(huì)遇到循環(huán)依賴的情況,簡(jiǎn)而言之就是Bean A的構(gòu)造器依賴于Bean B,Bean B的構(gòu)造器又依賴于Bean A。在這種情況下Spring會(huì)在編譯時(shí)拋出BeanCurrentlyInCreationException。
Class A
@Component public class ClassA { private ClassB classB; @Autowired public ClassA(ClassB classB) { this.classB = classB; } public void printClass() { System.out.println("Class A = " + this); System.out.println("Class B = " + classB); } }
Class B
@Component public class ClassB { private ClassA classA; @Autowired public ClassB(ClassA classA) { this.classA = classA; } public void printClass() { System.out.println("Class A = " + classA); System.out.println("Class B = " + this); } }
測(cè)試
@ContextConfiguration(classes = {ClassA.class, ClassB.class}) @RunWith(SpringRunner.class) public class MyTest { @Autowired private ClassA classA; @Autowired private ClassB classB; @Test public void name() { classA.printClass(); classB.printClass(); } }
原因
這時(shí)候運(yùn)行測(cè)試就會(huì)發(fā)現(xiàn)拋出了BeanCurrentlyInCreationException異常。產(chǎn)生這種情況的原因是,Spring在創(chuàng)建Bean時(shí),會(huì)首先實(shí)例化對(duì)象,然后再注入依賴。假設(shè)Spring首先創(chuàng)建Class A,那么就會(huì)發(fā)現(xiàn)在構(gòu)造器里有Class B的依賴,所以就會(huì)轉(zhuǎn)去創(chuàng)建Class B,又在Class B的構(gòu)造器里發(fā)現(xiàn)了對(duì)Class A的依賴,而此時(shí)Class A是還未初始化完的,因此又會(huì)轉(zhuǎn)去創(chuàng)建Class A,這樣就陷入了死循環(huán)。
解決方法
換成基于setter的依賴注入即可解決這個(gè)問題。因?yàn)榛趕etter的依賴注入會(huì)首先調(diào)用默認(rèn)構(gòu)造函數(shù)來實(shí)例化對(duì)象,然后再調(diào)用setter實(shí)現(xiàn)依賴注入。這樣在對(duì)象實(shí)例化的階段就沒有了任何依賴,因此Class A實(shí)例化完成后再調(diào)用Class B,Class B實(shí)例化完成后開始設(shè)值,而這時(shí)Class A已經(jīng)是實(shí)例化完成了的,所以可以成功引用到Class A。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Vue3源碼解讀effectScope API及實(shí)現(xiàn)原理
這篇文章主要為大家介紹了Vue3源碼解讀effectScope API及實(shí)現(xiàn)原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03SpringCloud?Gateway詳細(xì)分析實(shí)現(xiàn)負(fù)載均衡與熔斷和限流
這篇文章主要介紹了SpringCloud?Gateway實(shí)現(xiàn)路由轉(zhuǎn)發(fā),負(fù)載均衡,熔斷和限流,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07Java中ArrayList和LinkedList的區(qū)別
ArrayList和LinkedList在這個(gè)方法上存在一定的性能差異,本文就介紹了Java中ArrayList和LinkedList的區(qū)別,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06JavaMe開發(fā)自適應(yīng)滾動(dòng)顯示
我們??吹揭恍L動(dòng)顯示的實(shí)例,比如UC瀏覽器中,顯示網(wǎng)頁(yè)的內(nèi)容。當(dāng)內(nèi)容比較多時(shí),采用滾動(dòng)分頁(yè)顯示是合理的。在Canvas中繪圖中,多余的內(nèi)容被截?cái)嗔?。如何?shí)現(xiàn)滾動(dòng)分頁(yè)顯示呢?2015-09-09SpringBoot異常錯(cuò)誤頁(yè)面實(shí)現(xiàn)方法介紹
在項(xiàng)目訪問的時(shí)候我們經(jīng)常會(huì)發(fā)生錯(cuò)誤或者頁(yè)面找不到,比如:資源找不到404,服務(wù)器500錯(cuò)誤,默認(rèn)情況下springboot的處理機(jī)制都是去跳轉(zhuǎn)內(nèi)部的錯(cuò)誤地址:/error 和與之對(duì)應(yīng)的一個(gè)錯(cuò)誤頁(yè)面2022-09-09SpringCache緩存自定義配置的實(shí)現(xiàn)
本文主要介紹了SpringCache緩存自定義配置的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01