会产生循环依赖的场景:
一、通过构造方法进行依赖注入时产生的循环依赖问题。
二、通过setter方法进行依赖注入且是在多例(原型 prototype )模式下产生的循环依赖问题。
三、通过setter方法进行依赖注入且是在单例(singleton)模式下产生的循环依赖问题。
Spring所能解决的循环依赖是第三种,setter方式注入且是单例模式下
解决方案: 三级缓存 提前暴露待使用的实例
一级缓存:实例话完成的bean Cache of singleton objects: bean name to bean instance.
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
二级缓存 早期暴露的bean Cache of early singleton objects: bean name to bean instance. private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
//AOP时放的是代理类
三级缓存:单利bean工厂 Cache of singleton factories: bean name to ObjectFactory. private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
case1: 返回为null 正常第一次初始化取值时为空
case2: 非null 一级缓存非空 说明实例初始化完成,
三级缓存非空 说明可能存在循环依赖 eg: a->b b->a 在创建a调 addSingletonFactory() 放三级缓存之后,依赖属性赋值时populateBean()发现a 需要依赖b,然后getbean(b)发现b依赖a 然后走getbaen(a)的流程,会获取到三级缓存中内容让到二级缓存,返回a后继续创建b,然后把b放一级缓存,最后把a放一级缓存返回
原链接: https://www.processon.com/diagraming/61bc8d001efad406de49fc0f