核心表现是spring抛出beancurrentlyincreationexception或明确提示“dependencies form a cycle”,直接暴露闭环路径如syschannelcompanyservice→opmchannelaccountservice→syschannelcompanyservice,需按箭头检查对应类的注入点及@bean定义。

循环依赖导致启动失败,核心表现是应用卡在容器初始化阶段,抛出类似 BeanCurrentlyInCreationException 或明确提示 “dependencies form a cycle” 的错误。它不像 NoSuchBeanDefinitionException 那样指向“缺Bean”,而是 Spring 明确告诉你:“我绕不出这个圈”。排查关键在于快速定位闭环链,并判断是否可解、如何破。
看日志里有没有“form a cycle”字样
Spring Boot 2.6+ 默认禁止循环依赖,一旦检测到,会在启动失败报告中直接写出依赖闭环路径,例如:
afterTestController → AfterTestService → OpmMediaFlowControlService → ... → SysChannelCompanyService-
SysChannelCompanyService → OpmChannelAccountService → SysChannelCompanyService(闭环闭合)
这段文字就是最直接的证据。它不是推测,是 Spring 容器实际遍历时记录下来的依赖流向。复制整行,按箭头顺序检查对应类里的注入点(@Autowired、@Resource、构造器参数),就能快速锁定哪两个 Bean 在互相拉扯。
检查配置类和自定义 Bean 的创建逻辑
循环依赖高频出现在安全配置、过滤器、拦截器等需要手动注册 Bean 的场景。典型模式是:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 一个
@Configuration类用@Autowired注入了某个 Bean - 又在同一个类里用
@Bean方法返回了那个 Bean(或其依赖链上的 Bean)
比如 SecurityConfig 注入 JwtAuthenticationFilter,同时又通过 @Bean 方法创建它——Spring 就会陷入“先创建谁”的死锁。此时要检查所有 @Bean 方法的返回类型,以及它们参数中是否引用了当前配置类自身或其他正在创建中的 Bean。
区分构造器注入和 setter/字段注入
Spring 能自动解决 setter 或字段注入的单层循环依赖(A 依赖 B,B 依赖 A),但无法解决构造器注入形成的循环。如果你的类全部使用 final 字段 + 构造器注入,又出现循环依赖报错,基本可以确定是构造器级闭环。修复方式包括:
- 将其中一个 Bean 的注入方式改为
@Lazy(延迟加载) - 把某处构造器注入改为
@Autowired字段或 setter 注入 - 更彻底的做法:提取公共逻辑到第三方 Service,打破直接互引
启用 debug 模式辅助验证
在启动参数中加 --debug,或配置 logging.level.org.springframework.beans=DEBUG,Spring 会输出 Bean 创建的详细步骤,包括“正在创建 A”、“尝试注入 B”、“B 的创建触发对 A 的再次请求”等过程性日志。这对确认闭环节点非常有帮助,尤其当依赖链较长、人工追踪易遗漏时。










