跳到主要内容

吃透Spring源码(十三):Spring循环依赖源码分析

一,循环依赖

1,什么是循环依赖

循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。

在Spring中一般分为构造器循环依赖filed属性循环依赖

2,构造器循环依赖

实例化A对象需要依赖B对象,实例化B对象需要依赖A对象,所以最终两个都实例化不了。

@Component
public class A {



private B b;

public A(B b) {


this.b = b;
}
}

@Component
public class B {



private A a;

public B(A a) {


this.a = a;
}
}

Spring是无法解决构造期循环依赖的。

3,filed属性循环依赖

实例化A对象和实例化B对象之间并不相互影响,Spring是可以解决此种循环依赖的。

@Component
public class A {


@Autowired
private B b;
}

@Component
public class B {


@Autowired
private A a;
}

4,Spring是怎么解决循环依赖的?

三级缓存:

// 一级缓存,保存完整对象
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存,保存实例化并未初始化的对象
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存,保存ObjectFactory表达式,用于解决Aop
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);