spring循环依赖

Spring框架在处理bean的循环依赖时采用三级缓存机制。当创建bean过程中遇到循环依赖,如类A需要类B,类B也需要类A,Spring会将实例化的半成品bean放入缓存。在创建过程中,先将A放入三级缓存,接着创建B时从三级缓存获取A的实例,B晋升至二级缓存。由于AOP代理对象的问题,不能直接使用二级缓存,因此引入工厂池用于提前创建代理对象。最终,A和B分别晋升至一级缓存,完成循环依赖的解决。
摘要由CSDN通过智能技术生成

什么是spring循环依赖

  • 在创建bean的过程中,类a需要类b才能创建,类b也需要类a才能创建造成死循环

缓存怎么解决

  • bean的创建有三步,实例化,填充属性,初始化
  • 我们将实例化这种半成品放入一个缓存
  • a实例化把a放入,b实例化要a在缓存中有,可解决循环依赖

spring三级缓存

  • spring通过三级缓存来避免循环依赖
  • 创建a对象时发现需要b,把a放入三级缓存
  • 创建b时需要a,把a放入二级缓存并删除三级中的a
  • b直接晋升一级缓存并删除三级中的b
  • a晋升至一级缓存,创建完成

为什么不能用二级缓存呢

  • 因为有aop的代理对象,在创建b需要a时,二级缓存只能获取到原本对象而不能获取到代理对象

  • 创建代理对象有后置处理和提前处理两个入口,而后置处理是初始化之后才能执行的,所以我们的动态代理使用的提前处理
    在这里插入图片描述

  • 于是我们除了单例池,半成品池,我们又有了一个工厂池,对象实例化a之后放入工厂池,并且创建动态代理(因为后面b创建时get了a,需要提前引用)
    在这里插入图片描述

  • 然后创建b放入工厂池(因为a的刚刚已经搞了,创建b的时候没人引用b,所以不需要创建动态代理),a放入半成品池(二级缓存)
    在这里插入图片描述

  • 然后b填充属性初始化,通过后置处理创建代理对象,然后b放入一级缓存(单例池)
    在这里插入图片描述

  • 然后a进入一级缓存(已经创建代理,无需后置创建)

总结

  • 三级缓存时为了解决aop代理问题,创建b对象时,需要获取a(提前引用a,创建a时因为没有b所以没有提前引用),此时a在三级缓存通过提前引用获取代理对象给b访问,从而完美解决这个问题,虽然b也放在的三级缓存中,但因为没有引用b,所以b是没有提前代理的,等a到了二级,b就填充属性,初始化到了一级,然后才获取代理对象
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值