• Spring如何解决循环依赖


    spring如何解决循环依赖。相信大家都知道要通过三级缓存来解决,但具体的细节怎么样做的,可以一起来看一下。

    问什么会产生循环依赖,这就得从IOC说起了

    将对象交给容器控制,容器来创建对象,及其控制对象的生命周期。
    容器在实例化对象后,要注入属性,注入属性A的时候,A需要B,注入B的时候,B又需要A,这就导致了循环依赖。
    对于Bean的生命周期可以看这篇博客 Bean生命周期

    具体过程

    在这里插入图片描述

    • A创建过程中需要B,于是A将自己放到三级缓存里面,去实例化B
    • B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A
    • B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A放到一级缓存中。

    那么分别用一级缓存两级缓存会出现什么问题呢?

    一级缓存

    实例化A -> 将半成品的A放入singletonObjects中->填充A的属性时发现取不到B->实例化B->从singletonObjects中取出A填充B的属性->将成品B放入singletonObjects->将B填充到A的属性中->将成品A放入singletonObjects。

    问题:这种基本流程是通的,但是如果在整个流程进行中,有另一个线程要来取A,那么有可能拿到的只是一个属性都为null的半成品A,这样就会有问题。

    二级缓存

    使用singletonObjects和earlySingletonObjects

    成品放在singletonObjects中,半成品放在earlySingletonObjects中

    流程可以这样走:实例化A ->将半成品的A放入earlySingletonObjects中 ->填充A的属性时发现取不到B->实例化B->将半成品的A放入earlySingletonObjects中->从earlySingletonObjects中取出A填充B的属性->将成品B放入singletonObjects,并从earlySingletonObjects中删除B->将B填充到A的属性中->将成品A放入singletonObjects并删除earlySingletonObjects。

    问题:这样的流程是线程安全的,不过如果A上加个切面(AOP),这种做法就没法满足需求了,因为earlySingletonObjects中存放的都是原始对象,而我们需要注入的其实是A的代理对象。

    因为切面时需要代理对象所以存在了三及缓存
    三级缓存是用来存储代理Bean,当调用getBean()方法时,发现目标Bean需要通过代理工厂来创建,此时会将创建好的实例保存到三级缓存,最终也会将赋值好的Bean同步到一级缓存中。

  • 相关阅读:
    通达信l2行情接口怎么用?
    [每周一更]-(第72期):Docker容器瘦身方式
    Qt地铁智慧换乘系统浅学( 二 )将存储的站点线路信息绘制到graphicsView(图形视图部件)
    【科学文献计量】metaknowledge创建和处理知识网络的方法与 RC.networkCoAuthor()中的参数解释
    HTML数字倒计时效果附源码
    vue3.0新特性学习笔记
    javaWeb监听器Listener(三)定时清理session
    华为机试真题 Java 实现【积木最远距离】【2022.11 Q4 新题】
    Galaxy生信云平台|制作临床信息表/三线表/Table 1
    计算首屏时间
  • 原文地址:https://blog.csdn.net/qq_44620773/article/details/127653253