• spring的循环依赖


    > // A依赖了B
    class A{
    	public B b;
    }
    
    // B依赖了A
    class B{
    	public A a;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    一级缓存为:singletonObjects
    二级缓存为:earlySingletonObjects
    三级缓存为**:singletonFactories**

    首先创建A对象
    1.实例化A对象,singletonFactories<Aname,lamada表达式>
    2.填充A对象的b属性,暂时没有b对象-》去单例池中singletonObjects找,没有找到-》创建B对象
    3.填充其他属性
    4.初始化前,初始化
    5.初始化后
    6.放入单例池singletonObjects

    创建B对象
    2.1实例化B对象,singletonFactories<Bname,lamada表达式>
    2.2填充B对象的a属性-》去单例池中singletonObjects找,没找到,发现a对象正在创建中,出现了循环依赖,此时需要把(singletonFactories<Aname,lamada表达式>),这个表达式如果A不需要aop就返回a的原始对象,如果需要aop,就返回a的代理对象
    赋值给a属性,放入earlySingletonObjects 中
    2.3.填充其他属性
    2.4.初始化前,初始化
    2.5.初始化后
    2.6.放入单例池singletonObjects

    singletonObjects:缓存经过了完整生命周期的bean
    earlySingletonObjects:缓存未经过完整生命周期的bean,如果某个bean出现了循环依赖,就会提前把这个暂时未经过完整生命周期的bean放入earlySingletonObjects中,这个bean如果要经过AOP,那么就会把代理对象放入earlySingletonObjects中,否则就是把原始对象放入earlySingletonObjects,但是不管怎么样,就是是代理对象,代理对象所代理的原始对象也是没有经过完整生命周期的,所以放入earlySingletonObjects我们就可以统一认为是未经过完整生命周期的bean。
    singletonFactories:缓存的是一个ObjectFactory,也就是一个Lambda表达式。在每个Bean的生成过程中,经过实例化得到一个原始对象后,都会提前基于原始对象暴露一个Lambda表达式,并保存到三级缓存中,这个Lambda表达式可能用到,也可能用不到,如果当前Bean没有出现循环依赖,那么这个Lambda表达式没用,当前bean按照自己的生命周期正常执行,执行完后直接把当前bean放入singletonObjects中,如果当前bean在依赖注入时发现出现了循环依赖(当前正在创建的bean被其他bean依赖了),则从三级缓存中拿到Lambda表达式,并执行Lambda表达式得到一个对象,并把得到的对象放入二级缓存((如果当前Bean需要AOP,那么执行lambda表达式,得到就是对应的代理对象,如果无需AOP,则直接得到一个原始对象))。
    其实还要一个缓存,就是earlyProxyReferences,它用来记录某个原始对象是否进行过AOP了。

  • 相关阅读:
    SpringMVC 的三种异常处理方式详解
    openGauss系数据库逻辑复制实现双写
    【Android】MediaPlayer生命周期
    LabVIEW使用性能和内存信息
    FPGA学习之串口RS232
    【性能测试】稳定性/并发压力测试的TPS计算+5W并发场景设计...
    select/poll/epoll
    人机混合智能中跨域机理的研究
    【华为OD机试真题 JS】数组二叉树
    【BAT-表姐御用03MD(ren)命令】文件夹批量创建/命名/改名
  • 原文地址:https://blog.csdn.net/qq_38681231/article/details/125560292