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

public class AService{
private BService bService;
}

public class BService{
private AService aService;
}

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

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
此时BService生命周期变成:
1、class-->BeanDefinition
2、bService = new BService(); //原始对象, 放入primitiveObjectMap
3、属性填充 --> 填充aService属性 --> 从单例池找aService对应的Bean对象 --> 找不到 -->从ConcurrentHashMap可以推测出现了循环依赖 --> 从三级缓存执行lambda表达式 --> 执行AService的aop --> 得到aService的代理对象
4、初始化
5、BeanPostProcessor
6、添加bService的bean到单例池
这样就可以正常完成BService的bean创建,也就可以正常完成AService的bean创建。

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

你可能感兴趣的:(Spring三级缓存解决循环依赖的问题)