spring启动报beancurrentlyincreationexception,本质是循环依赖导致三级缓存失效,关键在定位环起点、分析注入方式(构造器注入必报错)、验证作用域与aop影响,并交叉印证四要素。

Spring 启动时报 BeanCurrentlyInCreationException,提示 “Requested bean is currently in creation”,基本可以断定是循环依赖问题。排查的关键不在于“有没有环”,而在于“Spring 在哪一步卡住、为什么没兜住”。下面从定位、分析、验证三步讲清楚怎么高效排查。
看报错堆栈,锁定触发点的 Bean 链路
异常信息里一定包含类似 A -> B -> C -> A 的引用路径。这是最直接的线索:
- 复制完整堆栈,重点关注
Caused by后面的几行,通常会显示正在创建哪个 Bean,又去获取了哪个 Bean - 找到第一个重复出现的 beanName(比如 A 出现两次),它就是环的起点和断点
- 检查这个 Bean 的注入方式:是构造器参数?
@Autowired字段?还是@Resource注解?注入方式决定 Spring 能否介入
查源码入口,确认是否落在三级缓存失效环节
Spring 判断循环依赖的核心逻辑在 DefaultSingletonBeanRegistry.getSingleton() 中。如果报错发生在该方法内,并且满足以下两个条件,说明三级缓存没起作用:
-
isSingletonCurrentlyInCreation(beanName) == true(目标 Bean 确实正在创建中) -
allowEarlyReference == false(不允许提前暴露早期引用)
这种情况常见于构造器注入——因为构造器执行时,对象还没实例化完成,Spring 连“半成品”都拿不出来,三级缓存里的 ObjectFactory 也来不及触发。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
验证依赖图,区分可解与不可解场景
不是所有循环依赖都会报错。用以下规则快速分类:
- 单例 + 字段或 setter 注入 → Spring 默认能解(走三级缓存:实例化后立即放入三级缓存工厂,属性填充时提供早期引用)
- 单例 + 构造器注入 → 必报错(构造阶段就需要完整依赖,无法提前暴露)
- 原型(
@Scope("prototype"))→ 必报错(每次新建,无缓存机制) - 含 AOP 代理(如
@Transactional、@Async)→ 容易出问题(代理对象生成时机可能晚于早期引用获取)
如果发现是构造器注入导致的,加 @Lazy 是最快验证手段:只给其中一个构造参数加,启动成功就反向证实了问题根源。
借助工具辅助可视化依赖关系
大型项目靠肉眼串代码容易漏掉间接依赖(比如 A → B → C → A)。可使用:
-
ApplicationContext.getBeanDefinitionNames()获取全部 Bean 名称,配合getBeanDefinition()查依赖列表 - IDEA 的 Spring 插件(如 Spring Boot Live Plugin),右键 Bean 可查看“Dependency Hierarchy”
- 启动时加 JVM 参数
-Dspring.trace=true,输出详细 Bean 创建日志(慎用于生产)
真正有效的排查,是把报错日志、注入方式、作用域、是否带切面这四点交叉印证,而不是盲目加 @Lazy 或改注入方式。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










