三级缓存在Spring中具体是如何工作的

发布于:2025-03-03 ⋅ 阅读:(38) ⋅ 点赞:(0)

Spring 的三级缓存机制是解决循环依赖问题的核心设计,同时兼顾了对 AOP 代理的支持。以下是三级缓存的具体工作原理和流程:

### 1. 三级缓存的定义
Spring 使用三个 `Map` 来管理 Bean 的创建过程:
- **一级缓存(`singletonObjects`)**:存放完全初始化完成的 Bean。
- **二级缓存(`earlySingletonObjects`)**:存放提前暴露的半成品 Bean,用于解决循环依赖。
- **三级缓存(`singletonFactories`)**:存放 Bean 的工厂对象,用于动态生成半成品 Bean 或代理对象。

### 2. 三级缓存的工作流程
假设存在两个 Bean:A 和 B,它们互相依赖(A 依赖 B,B 依赖 A),Spring 的三级缓存机制会按以下步骤工作:

#### (1) 创建 A
1. **实例化 A**:Spring 开始创建 A,调用其构造方法,得到一个原始对象。
2. **将 A 的工厂对象放入三级缓存**:将 A 的 `ObjectFactory` 放入 `singletonFactories`。
3. **属性注入**:在为 A 注入属性时,发现 A 依赖 B,于是开始创建 B。

#### (2) 创建 B
1. **实例化 B**:Spring 开始创建 B,调用其构造方法,得到一个原始对象。
2. **将 B 的工厂对象放入三级缓存**:将 B 的 `ObjectFactory` 放入 `singletonFactories`。
3. **属性注入**:在为 B 注入属性时,发现 B 依赖 A。
4. **从三级缓存中获取 A 的工厂对象**:Spring 从 `singletonFactories` 中找到 A 的工厂对象。
5. **生成半成品 A**:通过工厂对象调用 `getObject()` 方法,生成一个半成品 A,并将其放入二级缓存 `earlySingletonObjects`。
6. **将半成品 A 注入到 B**:完成 B 的属性注入,继续完成 B 的初始化。
7. **将 B 放入一级缓存**:完成 B 的初始化后,将 B 放入 `singletonObjects`,并从二级和三级缓存中移除。

#### (3) 完成 A 的初始化
1. **将初始化好的 B 注入到 A**:回到 A 的属性注入阶段,此时 B 已经完全初始化完成,将 B 注入到 A。
2. **完成 A 的初始化**:完成 A 的初始化后,将 A 放入一级缓存 `singletonObjects`,并从二级和三级缓存中移除。

### 3. 为什么需要三级缓存
- **支持 AOP 代理**:如果仅使用二级缓存,Spring 无法在 Bean 初始化前生成代理对象。三级缓存中的工厂对象可以在需要时动态生成代理对象。
- **解决循环依赖**:通过提前暴露半成品对象,打破循环依赖。
- **确保全局唯一性**:三级缓存允许 Spring 在 Bean 创建过程中动态决定返回原始对象还是代理对象。

### 4. 总结
Spring 的三级缓存机制通过以下方式解决循环依赖:
- **三级缓存**:存放 Bean 的工厂对象,用于动态生成半成品或代理对象。
- **二级缓存**:存放提前暴露的半成品 Bean,用于解决循环依赖。
- **一级缓存**:存放完全初始化完成的 Bean。

这种设计不仅解决了循环依赖问题,还支持了 AOP 代理,确保了 Spring 容器的灵活性和健壮性。


网站公告

今日签到

点亮在社区的每一天
去签到