spring 如何解决循环依赖

Spring 中使用了三级缓存的设计,来解决单例模式下的属性循环依赖问题。

解决的只是单例模式下 setter 方法注入bean属性循环依赖问题,

对于多例 Bean 和 构造方法注入 参数的循环依赖问题,并不能使用三级缓存设计解决。

缓存变化过程

  1. A实例化后、注入前放到3级缓存
  2.  A在注入属性时,发现有循环依赖,因此需要先getBean(B),实例化B,并将B也 从入3级缓存
  3. B放到3级缓存后,这时B要开始注入属性A,于是B找到了循环依赖A后,再从头执行getBean(A)方 法,getSingleton方法本次从缓存中取,然后将A设置到2级缓存,并且从3级缓存移除。
  4. B如愿以偿的拿到了A完成注入,然后B执行到DefaultSingletonBeanRegistry#addSingleton方 法,将B从3级缓存移出,放入1级缓存,到此B完成。B的完成是被动的,A需要它,才会先去创建 它
  5. A 还要继续自己的流程,然后populateBean方法将B注入。然后,A移出2级缓存,进入1级缓存, 整个流程完成! 

 为什么不能解决非单例、构造方法的循环依赖问题

为什么不能解决构造方法的循环依赖?

        创建对象会走构造方法,而构造方法的参数是互相依赖的对象,此时都还没有初始化创建完成,因此无法进行实例化创建

为什么不能解决多例的循环依赖?

        IoC容器只会管理单例Bean,并将单例Bean存入缓存。作用域为prototype时,每次getBean 都会创建新的对象,并不存入缓存,因此不可以解决循环依赖问题。

 解决方法

避免循环依赖:

引入第三个类C, A 和 B 都依赖 C, 而不是相互依赖

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值