Bean的循环依赖

问题

public class A {
    private B b;
}

public class B {
    private A a;
}
/**********************/

    


    


Bean的实例化分三步

 createBeanInstance实例化 -> populateBean 填充属性 -> initializeBean初始化

如何解决

为了解决单例的循环依赖问题,使用了三级缓存,递归调用发现Bean还在创建中即为循环依赖

/** 一级缓存:用于存放完全初始化好的 bean **/
private final Map singletonObjects = new ConcurrentHashMap(256);

/** 二级缓存:存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 */
private final Map earlySingletonObjects = new HashMap(16);

/** 三级级缓存:存放 bean 工厂对象,用于解决循环依赖 */
private final Map> singletonFactories = new HashMap>(16);

/**
bean 的获取过程:先从一级获取,失败再从二级、三级里面获取

创建中状态:是指对象已经 new 出来了但是所有的属性均为 null 等待被 init
*/

比如:1) A创建过程中需要B,于是A先放入到三级缓存中,去实例化B
2) B实例化时需要A,于是B先查一级缓存,没有,在查二级缓存,还是没有,再查三级缓存,找到啦!
3)然后三级缓存里面这个A放到二级缓存中,并删除三级缓存里面的A
4) B初始化完毕,放入到一级缓存中(此时B中A还再创建中状态)
5)然后接着创建A,此时B已经创建结束,直接从一级缓存中拿到B,然后完成创建,并将自己放到一级缓
存里面

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

一句话:先让最底层对象完成初始化,通过三级缓存与二级缓存提前曝光创建中的 Bean,让其他 Bean 率先完成初始化。

你可能感兴趣的:(Bean的循环依赖)