Spring 中的循环依赖有三个场景:
    1 构造器的循环依赖
    2 原型(prototype)Bean 属性循环依赖
    3 单例(singleton) Bean 属性循环依赖

    构造器的循环依赖问题无法解决,只能抛出 BeanCurrentlyInCreationException 异常

    原型(prototype)Bean 的循环依赖也不支持,因为注入的类是需要创建好的
    创建新的A时,发现要注入原型字段B,又创建新的B发现要注入原型字段A..

    Spring 通过提前暴露对象的方法解决单例属性的循环依赖

    在 DefaultSingletonBeanRegistry 类中,有三个 Map
    singletonFactories :单例对象工厂的cache 3earlySingletonObjects :提前暴光的单例对象的Cache 2singletonObjects:单例对象的cache 1

    在创建bean的时候,首先是从cache中获取这个单例的bean,这个缓存就是singletonObjects。
    如果获取不到,并且对象正在创建中,就再从二级缓存earlySingletonObjects中获取。
    如果还是获取不到且允许singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,
    如果获取到了则:从singletonFactories中移除,并放入earlySingletonObjects中。
    其实也就是从三级缓存移动到了二级缓存。

    A 的属性依赖了 B 的实例对象,B 的某个属性依赖了 A 的实例对象

    A 首先完成第一步初始化,A 提前暴露在 singletonFactories,
    A 继续进行初始化,发现依赖实例对象 B,没有 get 到 B,于是 B 开始初始化,
    B 初始中发现依赖 A,
    先找 singletonObjects 中没有(因为没有初始化完), earlySingletonObjects 中也没有,在 singletonFactories 中获取到 了未初始化完的 A 的引用,B 得以初始化完成;
    返回 A 中,A 也拿到了已经初始化完成的 B,最终 A 也完成初始化。

    因为加入singletonFactories三级缓存的前提是执行了构造器,所以构造器与原型 Bean 的循环依赖没法解决。