您好,登錄后才能下訂單哦!
循環依賴
定義: 循環依賴就是循環引用,就是兩個或多個Bean相互之間的持有對方,比方CircularityA引用CircularityB,CircularityB引用CircularityC,CircularityC引用CircularityA。形成一個環狀引用關系。
在使用Spring時,如果主要采用基于構造器的依賴注入方式,則可能會遇到循環依賴的情況,簡而言之就是Bean A的構造器依賴于Bean B,Bean B的構造器又依賴于Bean A。在這種情況下Spring會在編譯時拋出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); } }
測試
@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(); } }
原因
這時候運行測試就會發現拋出了BeanCurrentlyInCreationException異常。產生這種情況的原因是,Spring在創建Bean時,會首先實例化對象,然后再注入依賴。假設Spring首先創建Class A,那么就會發現在構造器里有Class B的依賴,所以就會轉去創建Class B,又在Class B的構造器里發現了對Class A的依賴,而此時Class A是還未初始化完的,因此又會轉去創建Class A,這樣就陷入了死循環。
解決方法
換成基于setter的依賴注入即可解決這個問題。因為基于setter的依賴注入會首先調用默認構造函數來實例化對象,然后再調用setter實現依賴注入。這樣在對象實例化的階段就沒有了任何依賴,因此Class A實例化完成后再調用Class B,Class B實例化完成后開始設值,而這時Class A已經是實例化完成了的,所以可以成功引用到Class A。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。