zoukankan      html  css  js  c++  java
  • spring怎么解决循环依赖

    spring怎么解决循环依赖?
    首先会根据 beanName 从单例 bean 缓存中获取,如果不为空则直接返回

    主要是从三个缓存中获取 (称他们为3级缓存),分别是:
    singletonObjects (1 单例对象的cache)
    earlySingletonObjects(2 提前暴光的单例对象的Cache )
    singletonFactories (3 单例对象工厂的cache )
    getSingleton() 整个过程如下:
    首先从一级缓存 singletonObjects 获取,如果没有且当前指定的 beanName 正在创建,
    就再从二级缓存中 earlySingletonObjects 获取,如果还是没有获取到且运行 singletonFactories 通过 getObject() 获取,
    则从三级缓存 singletonFactories 获取,如果获取到则,通过其 getObject() 获取对象,
    并将其加入到二级缓存 earlySingletonObjects 中 从三级缓存 singletonFactories 删除,这样就从三级缓存升级到二级缓存了

    从缓存中获取,但是缓存中的数据从哪里添加进来的呢?
    提前将创建好但还未进行属性赋值的的Bean放入缓存中
    一个 bean 要具备如下条件才会添加至缓存中:
    1、单例
    2、运行提前暴露 bean
    3、当前 bean 正在创建中
    如果二级缓存(earlySingletonExposure)存在,singletonFactories 这个三级缓存才是解决 Spring Bean 循环依赖的诀窍所在。
    同时这段代码发生在 createBeanInstance() 方法之后,也就是说这个 bean 其实已经被创建出来了,但是它还不是很完美(没有进行属性填充和初始化)
    ,但是对于其他依赖它的对象而言已经足够了(可以根据对象引用定位到堆中对象),能够被认出来了,
    所以 Spring 在这个时候选择将该对象提前曝光出来让大家认识认识

    所以我们基本上可以确定 Spring 解决循环依赖的方案了:Spring 在创建 bean 的时候并不是等它完全完成,
    而是在创建过程中将创建中的 bean 的 ObjectFactory 提前曝光(即加入到 singletonFactories 缓存中),
    这样一旦下一个 bean 创建的时候需要依赖 bean ,则直接使用 ObjectFactory 的 getObject() 获取了,也就是 getSingleton()中的代码片段了。

    描述下就上面那个循环依赖 Spring 解决的过程:首先 A 完成初始化第一步并将自己提前曝光出来
    (通过 ObjectFactory 将自己提前曝光),在初始化的时候,发现自己依赖对象 B,
    此时就会去尝试 get(B),这个时候发现 B 还没有被创建出来,然后 B 就走创建流程,在 B 初始化的时候,同样发现自己依赖 C,C 也没有被创建出来,
    这个时候 C 又开始初始化进程,但是在初始化的过程中发现自己依赖 A,于是尝试 get(A),这个时候由于 A 已经添加至缓存中(一般都是添加至三级缓存 singletonFactories )
    ,通过 ObjectFactory 提前曝光,所以可以通过 ObjectFactory.getObject() 拿到 A 对象,C 拿到 A 对象后顺利完成初始化,然后将自己添加到一级缓存中,
    回到 B ,B 也可以拿到 C 对象,完成初始化,A 可以顺利拿到 B 完成初始化。到这里整个链路就已经完成了初始化过程了

    总体就是 把循环的A初始化放到通过 ObjectFactory 放到 2级缓存 。。。 C尝试去缓存中 get A C拿到 A 对象后顺利完成初始化,然后将自己添加到一级缓存中,
    回到 B ,B 也可以拿到 C 对象,完成初始化

    Spring对单例的底层实现,到底是饿汉式单例还是懒汉式单例呢?
    Spring框架对单例的支持是采用单例注册表的方式进行实现的

    群交流(262200309)
  • 相关阅读:
    hadoop2.2 伪分布式环境
    java Map实现的cache manager
    Java语言基础(九)
    Java语言基础(八)
    Java语言基础(七)
    Java语言基础(六)
    Java语言基础(五)
    Java语言基础(四)
    Java语言基础(三)
    Java语言基础(二)
  • 原文地址:https://www.cnblogs.com/webster1/p/12246160.html
Copyright © 2011-2022 走看看