Spring Boot 循环依赖

返回 面试 · 速查全集 SpringBoot常见面试题

两个及以上 Bean 相互注入形成闭环。Spring 仅部分场景可解决;Boot 2.6+ 默认禁止循环依赖。

详细机制见 循环依赖


结论速记

问题答案
能解决吗?单例 + 字段/setter 注入可以(三级缓存)
构造器注入循环依赖?不能,实例化阶段就需要对方,直接报错
Boot 2.6+ 默认?禁止,报 BeanCurrentlyInCreationException
推荐做法?从设计上消除循环依赖(拆服务、事件、中间层)

三级缓存(简述)

缓存内容
一级 singletonObjects完整 Bean
二级 earlySingletonObjects早期引用(已实例化、未填完属性)
三级 singletonFactoriesObjectFactory,支持 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 都会无限循环。


相关笔记