跳到正文
Elaine Blog
返回

三级缓存能解决什么循环依赖

Spring 生态与源码

三级缓存不是通用的“循环依赖解决器”。它只在单例 Bean 已实例化但尚未完成初始化时,协调早期引用和最终代理的一致性;构造器互相依赖时,对象根本无法先创建。

Table of contents

Open Table of contents

三个缓存保存什么

缓存内容
一级 singletonObjects已完成生命周期的单例
二级 earlySingletonObjects已暴露的早期实例引用
三级 singletonFactories能生成早期引用的 ObjectFactory

三级保存工厂而不是直接保存对象,是因为 AOP 后置处理器可能需要返回早期代理。这样其他 Bean 注入的引用与最终暴露引用保持一致。

构造器循环为什么失败

若 A 构造器需要 B,B 构造器又需要 A,容器在任何一个对象实例化前都缺少另一个完整参数。此时没有可放入早期缓存的实例,应该抛出创建中异常。

可以给最小 IoC 容器下载增加 A→B→A 测试,观察递归创建。 真实教学改进应维护“正在创建”集合并报告依赖路径,而不是等栈溢出。

属性循环为什么有时能工作

Setter 或字段注入让容器先调用无参构造器得到 A,再暴露早期引用,随后创建 B 并把 A 注入,最后回头完成 A。但这依赖单例作用域、具体配置和代理行为, Spring Boot 默认也不鼓励依赖循环。

能启动不代表设计合理。A 与 B 互相知道彼此,往往说明职责没有分开,测试也更难隔离。

优先重构循环

重构后用业务行为测试证明顺序与事务边界没有改变。删除循环的目标是澄清所有权,而不只是让 Context 变绿。

下一步

阅读配置类、组件扫描与条件装配,理解 BeanDefinition 从哪里进入容器。


分享这篇文章:

上一篇
构造器推断与依赖解析
下一篇
配置类、组件扫描与条件装配