• 循环依赖


    一、总说循环依赖描述及解决方案

    描述:A对象中有b属性,B对象中有a属性,此时A、B两个对象相互引用,可能会出现循环依赖问题

    解决方案:若出现循环依赖问题,可以采用三级缓存来解决此问题

     二、造成循环依赖过程

    1、A对象实例化,b属性设置默认值

    2、A对象初始化,给b填充属性,从容器中寻找B对象

        如果找到B对象,直接返回赋值即可

        如果找不到B对象,创建B对象

    3、B对象实例化,a属性设置默认属性

    4、B对象初始化,给a填充属性,从容器中寻找A对象,此时A对象还没有初始化结束,形成闭环(循环依赖)

     分析:

      此时图中为一个闭环操作,及循环依赖,若不想出现这种场景,则需要在创建A对象这个步骤中保证容器中有A对象的存在

    解决:

      在Spring中对象的创建过程分为实例化和初始化,实例化但未初始化的对象是可以被其他对象引用的

      这时,只要将实例化但未初始化的对象提前暴露,让其他对象可以进行引用,就完成了循环依赖的解环操作

      提前暴露的对象放到一、二、三级缓存中

    三、三级缓存

    如果发生循环依赖的对象,不需要代理的话,只需要二级缓存足矣解决所有问题。但是当存在代理之后就无法解决了,必须使用三级缓存来解决

    1、beanName和lamda表达式放到了三级缓存中,bean没有放到任何一级缓存中

    2、每次找缓存优先从一级-->二级-->三级,在根据beanName去寻找对象时,可以在三级缓存中找到lambda表达式。通过singletonFactory.getObject()获取到对象放到二级缓存中

    3、在二级缓存中存储的对象实例化完成但未初始化(A对象)

    4、B对象拿到了半成品A对象,B对象就可以初始化成功,紧接着A对象也可以拿到B对象,A对象也就初始化成功了

     三级缓存中并不是严格的从三级到二级到一级,这样的一个对象转化顺序,有可能在三级和一级中有对应,也有可能在一二三级中都有对象

    作者:http://cnblogs.com/lyc-code/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权力。

  • 相关阅读:
    第三章 IPtables防火墙基本使用
    第四章 SFTP命令使用
    第三章 AWS快照创建实例启动失败排查解决
    第三章 windows下启动停止服务
    第六章 Sersync实时同步服务介绍
    第四章 IPtables防火墙进阶使用
    倍增求LCA
    求割点
    C. BAString
    E. MEX and Increments
  • 原文地址:https://www.cnblogs.com/lyc-code/p/14480638.html
Copyright © 2020-2023  润新知