Spring三级缓存解决循环依赖
Spring中Bean的创建过程(生命周期)
Spring的refresh()方法 把扫描XML和注解的Bean解析成BeanDefintion并注册到beanFactory,再注册一些Bean处理器后再调用finishBeanFactoryInitialization(beanFactory)创建单例Bean,步骤如下:
- 实例化(掉用构造函数创建一个为填充任何属性的Bean)
- 属性装配(@Autowried 依赖注入)
- 初始华(aop增强)
- 销毁
Spring的三级缓存作用和getSingleton()
//一级缓存,存放完整的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存,存放未填充属性的代理Bean或无代理Bean
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 三级缓存,存放所有单例Bean的工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//获取单例Bean方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//若对象被代理此步骤获取代理后的Bean
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
为什么不是二层呢?
首先第三级是产生Bean的工厂,我们不能删除,第一层存放的是完整的Bean我们也不能删除,只能删掉第二层了。在无AOP的情况的循环依赖还是可以解决的。
A(B)
B(A)
但是在有AOP的情况下,同时有代理类和非代理(A和AP),该怎么处理呢?这里有一个方案:ObjectFactory直接产生代理类AP而不是A,再进行依赖注入,但是这更改了Bean的生命周期。这是不希望看到的(或者这里还有其他缺点或致命缺陷我没有想到)。所以使用了三层缓存,在未发生循环依赖时不打乱Bean的生命周期,增加一层缓存用于存放代理类,也使得三个缓存的分工明确。但是在有aop的情况下,打破生命周期还是无法避免的。
AOP增强的循环依赖会打破Bean的生命周期
假设类A和B都用了AOP增强,那么Spring会为其创建动态代理类AP和BP。这里大家思考一下,A依赖B还是BP呢?没错,A中需要的是增强后的BP,B同理依赖增强后的AP,用如下方式表示:
A(BP)
B(AP)
可以看到A这边的AP(A代理类)创建被提前了,而B这边的生命周期是没有问题的,这是使用AOP且出现循环依赖的情况时无法避免的。