Spring中的循環依賴


循環依賴

在使用Spring時,如果主要采用基於構造器的依賴注入方式,則可能會遇到循環依賴的情況,簡而言之就是Bean A的構造器依賴於Bean BBean 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 BClass B實例化完成后開始設值,而這時Class A已經是實例化完成了的,所以可以成功引用到Class A


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM