Spring 循环依赖问题(三级缓存)

我们常常会说“Spring是通过三级缓存来解决循环依赖问题的”,那么

  • 所有的循环依赖问题都解决了吗?
  • 为什么是三级缓存?
  • 每级缓存分别存的是什么?

带着上面几个问题分析一下整个循环依赖的过程。

现在有两个类AService和BService,其中AService依赖BService,BService也依赖AService。

@Component
public class AService {
    @Autowired
    private BService bService;
}

@Component
public class BService {
    @Autowired
    private AService aService;
}

 我们假定AService Bean先创建,此时

单例Bean之间的循环依赖过程

上图就是整个Spring单例Bean的循环依赖过程,该流程只针对属性注入和sertter方法注入。对于构造方法循环依赖Spring并没有解决,会报错。相当于存入三级缓存的半成品的Bean都实例化不出来(三级缓存中提前AOP函数其中一个参数是刚实例化完的半成品AService对象)。

原型(多例)Bean之间的循环依赖

Spring也没有解决原型Bean之间的循环依赖问题,如果AService和BService都是原型Bean会直接报错

大致分析一下其循环依赖过程,对于原型Bean来说每次依赖都会创建一个新的对象,整个过程就会变成 AService ---> 创建BService ---> 创建AService ---> 又创建个新的BService ......无限循环下去。但是其中只要有一个Bean是单例的,就可以正常循环依赖,无非就是多绕几次。

最后回答一下文章开头的问题

  • 所有的循环依赖问题都解决了吗?
    • 没有,原型Bean以及单例Bean之间构造方法循环依赖没有解决
  • 为什么是三级缓存?
    • 其实只有【二级缓存】也能解决循环依赖问题,比如在存入三级缓存的位置把需要AOP就提前AOP存入【二级缓存】不需要AOP的把半成品AService Bean也存入【二级缓存】,在BService依赖AService的时候直接从【二级缓存】取出进行注入。但是这样的话所有需要AOP的Bean都要提前AOP了,这显然不符合Bean生命周期流程(AOP是在初始化后进行的)。Spring是在BService注入AService判断出AService正在创建中(即发生了循环依赖)时会存入二级缓存,AService需要AOP就提前AOP存入代理对象,不需要AOP就存入半成品的AService Bean,那么第三级缓存就是必要的,不然用什么来提前AOP呢?
  • 每级缓存分别存的是什么?
    • 一级缓存:单例池
    • 二级缓存:要么是原始的半成品Bean,要么是提前AOP之后的Bean(是有存在循环依赖时才会存)
    • 三级缓存:工厂方法(判断需要AOP吗,需要则进行AOP返回AOP后的代理对象,不需要则返回Bean)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值