1、Spring三级缓存是什么,过程是怎么样的?
Spring 中的三级缓存主要用于单例 Bean 的生命周期管理,特别是在循环依赖时,它通过不同阶段暴露 Bean 实例来确保依赖注入的顺利完成。缓存的内容如下:
-
一级缓存 (singletonObjects) :存储完全初始化的单例 Bean。该缓存中存储的是已经完成初始化的 Bean 对象,包括所有的属性注入和生命周期回调方法(如 @PostConstruct)都已完成。
-
二级缓存 (earlySingletonObjects) :存储实例化但尚未完成所有初始化步骤的 Bean 引用。也就是 Bean 已经完成了实例化,并完成了依赖注入(如字段注入),但可能还没有执行初始化方法(如 @PostConstruct)。二级缓存用于解决循环依赖问题,当需要注入的 Bean 还没有完全初始化时,可以先返回该 Bean 的早期引用。
-
三级缓存 (singletonFactories) :存储的是创建 Bean 的工厂(ObjectFactory),而不是直接存储 Bean 实例 。这些工厂延迟返回真正的 Bean 实例,直到它们完成初始化。三级缓存用于处理 循环依赖 的核心,当一个 Bean 处于创建过程中,另一个 Bean 依赖它时,可以从三级缓存中获取一个工厂对象,该工厂会在 Bean 完全初始化后,生成一个完整的 Bean 实例。
2、从缓存中获取单例对象
2.1、代码解读
java
public Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1. 检查一级缓存,获取已完成初始化的 Bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.singletonsCurrentlyInCreation.contains(beanName)) {
// 2. 如果一级缓存没有,且 Bean 正在创建中,则检查二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 3. 如果二级缓存也没有,允许提前引用时,检查三级缓存
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 4. 从三级缓存中获取 Bean 实例
singletonObject = singletonFactory.getObject();
// 5. 将生成的对象放入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 6. 从三级缓存中移除工厂
this.singletonFactories.remove(beanName);
}
}
}
// 7. 返回从缓存中获取的单例对象
return singletonObject;
}
2.2、执行流程
-
一级缓存 (singletonObjects):
检查一级缓存,获取完全初始化的 Bean。
如果一级缓存中存在该对象,则直接返回。
-
二级缓存 (earlySingletonObjects):
如果一级缓存中没有找到该对象,且该对象正在创建过程中(this.singletonsCurrentlyInCreation),则检查二级缓存。
如果二级缓存中存在早期暴露的 Bean,则直接返回。
-
三级缓存 (singletonFactories):
如果二级缓存中也没有,并且允许提前引用(allowEarlyReference 为 true),则从三级缓存中获取工厂对象(ObjectFactory)。
调用 ObjectFactory.getObject() 方法生成 Bean 实例。
将生成的实例放入二级缓存,同时从三级缓存中移除对应的工厂。