循环依赖,在创建A的时候需要注入成员变量B,而当创建B的时候又需要注入成员变量A,这就到之后bean无法被创建完成加入spring的单例池,不停地循环创建新的bean。
public class A {
B b;
public A(B b){
this.b=b;
}
}
public class B {
A a;
public B(A a){
this.a=a;
}
}
-
如果想要打破循环有两种方式
-
使用
@lazy
注解,延迟加载,当使用时才延迟加载进来,这时A与B的对象已经创建完成,虽然成员变量还是空值,但是当时用时两个对象的属性都会装载完成。 -
使用
@autowire
注解,spring使用三级缓存解决循环依赖的问题。
假如先从A到B的创建,创建过程如下
当创建A对象的bean时
1.实例化new一个A对象,创建一个lambda表达式加入第三层缓存(用于判断返回普通对象,还是AOP的代理对象)
2.进行成员变量的注入(@autowired注入)
3.初始化前(初始化前,可以对bean进行类似指定数据库的连接地址,账号密码等信息的注入)
4.初始化
5.初始化后(判断是否需要AOP,决定生成代理对象,前面已经提前生成代理对象的bean就直接用,普通对象也直接用没有影响,因为对象没有改变,后面的实例化会将bean对象装配完整)
6.加入单例池
需要创建B对象的bean,注入到A中
1.实例化new一个B对象,创建一个lambda表达式。
2.进行成员变量的注入-->寻找单例池-->判断发现成员变量正在创建,判断出现循环依赖-->寻找第二级缓存查看有没有半成品A-->寻找第三级缓存,创建A的bean对象(普通对象或是AOP代理对象),删除该三级lambda-->将生成的bean半成品加入第二级缓存。
3.初始化前
4.初始化
5.初始化后(判断是否需要AOP,决定生成代理对象)
6.加入单例池