Spring Boot 循环依赖
→ 返回 面试 · 速查全集 SpringBoot常见面试题
两个及以上 Bean 相互注入形成闭环。Spring 仅部分场景可解决;Boot 2.6+ 默认禁止循环依赖。
详细机制见 循环依赖。
结论速记
| 问题 | 答案 |
|---|---|
| 能解决吗? | 单例 + 字段/setter 注入可以(三级缓存) |
| 构造器注入循环依赖? | 不能,实例化阶段就需要对方,直接报错 |
| Boot 2.6+ 默认? | 禁止,报 BeanCurrentlyInCreationException |
| 推荐做法? | 从设计上消除循环依赖(拆服务、事件、中间层) |
三级缓存(简述)
| 缓存 | 内容 |
|---|---|
一级 singletonObjects | 完整 Bean |
二级 earlySingletonObjects | 早期引用(已实例化、未填完属性) |
三级 singletonFactories | ObjectFactory,支持 AOP 早期代理 |
流程:创建 A → 放三级 → 注入 B → 创建 B → 需要 A → 从缓存拿 A 早期引用 → B 完成 → A 完成。
构造器注入在「创建 A 实例」时就必须有 B,无法提前暴露 A,故无法解决。
临时允许(不推荐)
spring:
main:
allow-circular-references: true消除循环依赖的常见手段
A → B → A 改为:
· A 依赖 C,C 依赖 B(引入中间层)
· 用 ApplicationEvent 解耦
· @Lazy 延迟注入其中一侧(治标)
· 合并职责过重的 Service
面试追问
Q:为什么三级缓存而不是二级?
A:三级存 ObjectFactory,在需要早期引用时才生成对象(含 AOP 代理),避免过早暴露原始对象。
Q:prototype 循环依赖?
A:不解决;每次 new 都会无限循环。