關於spring迴圈依賴的一點小感悟

不會前端的後端程式猿不是好司機發表於2020-04-06

首先,spring是支援setter迴圈依賴的,但是不支援基於建構函式的迴圈依賴注入。一直不太明白其中原理,直到看到官方文件中的這麼一段話

Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken-and-egg scenario).

大概意思就是說,對於A和B之間的迴圈依賴,會強制使另一個bean注入一個未完全初始化完成的自己。

提出假設

  • 既然是未初始化完成的bean,那其被注入的時候生命週期方法init-method就是應該未被執行過的。
  • A和B,誰會注入一個未初始化完成的依賴呢?如果A先註冊,則B在查詢依賴注入的A應該是一個未完全初始化的A。

話不多說,上程式碼

1、建立兩個bean互相依賴

class A{

    public A(){
        System.out.println("開始建立a");
    }
    private B b;

    @Autowired
    public void setB(B b){
        System.out.println("b 被注入!");
        this.b=b;
    }

    @PostConstruct
    public void init(){
        System.out.println("a 初始化完成!");
    }
}

class B{
    public B(){
        System.out.println("開始建立b");
    }
    private A a;
    @Autowired
    public void setA(A a){
        System.out.println("a 被注入!");
        this.a=a;
    }
    @PostConstruct
    public void init(){
        System.out.println("b初始化完成!");
    }

}
複製程式碼

2、啟動容器

    AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext();
    context.register(A.class);
    context.register(B.class);
    context.refresh();
複製程式碼

3、分析結果

關於spring迴圈依賴的一點小感悟

結論

  • spring迴圈依賴注入中,其中有一個依賴是在fully initialized之前被注入的
  • 後註冊的bean注入的依賴是一個未完全初始化的bean

相關文章