Spring三级缓存解决循环依赖的问题

public class AService{
private BService bService;
}

public class BService{
private AService aService;
}

三级缓存:
一级:单例池,ConcurrentHashMap
二级:原始对象(or代理对象)缓存,ConcurrentHashMap
三级:BeanFactory缓存,ConcurrentHashMap<bean, lambda(原始对象)>

AService生命周期:
1、class-->BeanDefinition
2、aService = new AService(); //原始对象
3、属性填充 --> 填充bService属性 --> 从单例池找bService对应的Bean对象 --> 找不到 --> 创建bService
4、初始化
5、BeanPostProcessor
6、添加aService的bean到单例池

从AService生命周期3进入:
BService生命周期:
1、class-->BeanDefinition
2、bService = new BService(); //原始对象
3、属性填充 --> 填充aService属性 --> 从单例池找aService对应的Bean对象 --> 找不到 --> 创建aService
4、初始化
5、BeanPostProcessor
6、添加bService的bean到单例池

在第三步形成循环,解决方式,引入二级缓存:
将第二步的原始对象放入缓存(假设是primitiveObjectMap);
此时BService生命周期变成:
1、class-->BeanDefinition
2、bService = new BService(); //原始对象, 放入primitiveObjectMap
3、属性填充 --> 填充aService属性 --> 从单例池找aService对应的Bean对象 --> 找不到 -->从primitiveObjectMap获取aService 的原始对象
4、初始化
5、BeanPostProcessor
6、添加bService的bean到单例池
这样就可以正常完成BService的bean创建,也就可以正常完成AService的bean创建。

但是在第五步加入AOP操作则会出现问题;
5、BeanPostProcessor --> aop --> 代理对象
会将代理对象加入单例池,但是赋值给BService的是原始对象;


image.png

可以在出现循环依赖的情况下将AOP提前即可:
2、bService = new BService();--> aop --> 代理对象 //将代理对象放入primitiveObjectMap
但是循环依赖需进入步骤3才能知道存在循环依赖;
此时可以加入三级缓存:
2、bService = new BService(); //原始对象 ConcurrentHashMap<aService, lambda(原始对象)>
此时BService生命周期变成:
1、class-->BeanDefinition
2、bService = new BService(); //原始对象, 放入primitiveObjectMap
3、属性填充 --> 填充aService属性 --> 从单例池找aService对应的Bean对象 --> 找不到 -->从ConcurrentHashMap<aService, lambda(原始对象)>可以推测出现了循环依赖 --> 从三级缓存执行lambda表达式 --> 执行AService的aop --> 得到aService的代理对象
4、初始化
5、BeanPostProcessor
6、添加bService的bean到单例池
这样就可以正常完成BService的bean创建,也就可以正常完成AService的bean创建。

另参考:https://www.jianshu.com/p/6cbbb6a9b3fd

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容