spring解决循环依赖
spring 中使用了三级缓存的设计,来解决单例模式下的属性循环依赖问题。
解决的只是单例模式下 setter 方法注入bean属性循环依赖问题,
对于多例 bean 和 构造方法注入 参数的循环依赖问题,并不能使用三级缓存设计解决。
缓存变化过程
- a实例化后、注入前放到3级缓存
- a在注入属性时,发现有循环依赖,因此需要先getbean(b),实例化b,并将b也 从入3级缓存
- b放到3级缓存后,这时b要开始注入属性a,于是b找到了循环依赖a后,再从头执行getbean(a)方 法,getsingleton方法本次从缓存中取,然后将a设置到2级缓存,并且从3级缓存移除。
- b如愿以偿的拿到了a完成注入,然后b执行到defaultsingletonbeanregistry#addsingleton方 法,将b从3级缓存移出,放入1级缓存,到此b完成。b的完成是被动的,a需要它,才会先去创建 它
- a 还要继续自己的流程,然后populatebean方法将b注入。然后,a移出2级缓存,进入1级缓存, 整个流程完成!
为什么不能解决非单例、构造方法的循环依赖问题
为什么不能解决构造方法的循环依赖?
- 创建对象会走构造方法,而构造方法的参数是互相依赖的对象
- 此时都还没有初始化创建完成,因此无法进行实例化创建
为什么不能解决多例的循环依赖?
- ioc容器只会管理单例bean,并将单例bean存入缓存。
- 作用域为prototype时,每次getbean 都会创建新的对象,并不存入缓存,因此不可以解决循环依赖问题。
解决方法
避免循环依赖:
引入第三个类c, a 和 b 都依赖 c, 而不是相互依赖
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论