天天看點

Spring源碼學習:setter循環依賴

1.案例:

@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }

    public B getB() {
        return b;
    }

    public void f(){
        System.out.println(b);
    }
}
           
@Component
public class B {
    private A a;

    @Autowired
    public void setA(A a) {
        this.a = a;
    }
    public void f(){
        System.out.println(a);
    }
}
           
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        A a = ctx.getBean(A.class);
        a.f();
        System.out.println(a.getClass());
        System.out.println(a.getB().getClass());
    }
}
           

2.源碼:

1.1.在三級緩存中查找a(沒找到)

Spring源碼學習:setter循環依賴

1.2.未找到,開始建立a的Bean執行個體

1.2.2.将執行個體對象包裝為WrappedInstance

Spring源碼學習:setter循環依賴

1.2.3.将該執行個體添加到第三級緩存中

Spring源碼學習:setter循環依賴

1.2.4.開始初始化a執行個體的所有屬性

Spring源碼學習:setter循環依賴

1.2.4.1.開始初始化a的屬性b,b是setter循環依賴屬性

1.2.4.2.在三級緩存中查找b

1.2.4.3.未找到,開始建立b的Bean執行個體

1.2.4.4.通過反射對B類執行個體化

1.2.4.5.将執行個體對象包裝為WrappedInstance

1.2.4.6.将該執行個體添加到第三級緩存中

1.2.4.7.開始初始化b執行個體的所有屬性

1.2.4.7.1.開始初始化b的屬性a,a是setter循環依賴屬性

1.2.4.7.2.在三級緩存中查找a

1.2.4.7.3.在第三級緩存中找到,擷取a的執行個體

重複1.1.的工作

1.2.4.7.4.将a執行個體從第三級緩存降到第二級緩存

Spring源碼學習:setter循環依賴

1.2.4.7.5.初始化b執行個體的所有屬性結束,b的Bean建立完成

1.2.4.7.6.将b添加到第一級緩存,并從後兩級中移除

Spring源碼學習:setter循環依賴

1.2.4.8.初始化a執行個體的所有屬性結束,a的Bean建立完成

1.2.4.9.将a添加到第一級緩存,并從後兩級中移除

3.流程總結:

1.開始執行個體化a

1.1.在三級緩存中查找a

1.2.未找到,開始建立a的Bean執行個體

1.2.1.通過反射對A類執行個體化

1.2.2.将執行個體對象包裝為WrappedInstance

1.2.3.将該執行個體添加到第三級緩存中

1.2.4.開始初始化a執行個體的所有屬性

1.2.4.1.開始初始化a的屬性b,b是setter循環依賴屬性

1.2.4.2.在三級緩存中查找b

1.2.4.3.未找到,開始建立b的Bean執行個體

1.2.4.4.通過反射對B類執行個體化

1.2.4.5.将執行個體對象包裝為WrappedInstance

1.2.4.6.将該執行個體添加到第三級緩存中

1.2.4.7.開始初始化b執行個體的所有屬性

1.2.4.7.1.開始初始化b的屬性a,a是setter循環依賴屬性

1.2.4.7.2.在三級緩存中查找a

1.2.4.7.3.在第三級緩存中找到,擷取a的執行個體

1.2.4.7.4.将a執行個體從第三級緩存降到第二級緩存

1.2.4.7.5.初始化b執行個體的所有屬性結束,b的Bean建立完成

1.2.4.7.6.将b添加到第一級緩存,并從後兩級中移除

1.2.4.8.初始化a執行個體的所有屬性結束,a的Bean建立完成

1.2.4.9.将a添加到第一級緩存,并從後兩級中移除

Spring源碼學習:setter循環依賴

4.三級緩存機制

一級:初始化完成的Bean

二級:執行個體化待初始化的對象

三級:對象工廠類,提供對象代理功能