You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.1.5使用Setter/Field Injection仍遇循环依赖问题求助

循环依赖问题排查与解决方案(Java17 + Spring Boot 3.1.5)

原本预期Setter注入或Field注入可解决循环依赖,但在Java17 + Spring Boot 3.1.5项目中,两种方式均触发循环依赖错误,以下是相关代码、报错信息、项目结构及解决方案:

1. 注入方式代码示例

Setter注入

BeanA

@Component
public class BeanA {

    BeanA() {
        System.out.println("BeanA constructor called !!!");
    }

    private BeanB beanB;

    @Autowired
    public void setBeanB(BeanB beanB) {
        System.out.println("Setting property beanB of BeanA instance");
        this.beanB = beanB;
    }
}

BeanB

@Component
public class BeanB {

    BeanB() {
        System.out.println("BeanB constructor called !!!");
    }

    private BeanA beanA;

    @Autowired
    public void setBeanA(BeanA beanA) {
        System.out.println("Setting property beanA of BeanB instance");
        this.beanA = beanA;
    }
}

Field注入

BeanA

@Component
public class BeanA {

    @Autowired
    BeanB beanB;

    BeanA(){
//        System.out.println("beanA init!");
    }
}

BeanB

@Component
public class BeanB {

    @Autowired
    BeanA beanA;

    BeanB(){
        System.out.println("beanB init!");
    }
}

2. 报错信息

**************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  beanA
↑     ↓
|  beanB
└─────┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

3. 项目结构

com.demo.example
├── MainApp.java
├── setterInjection
│   ├── BeanA.java
│   └── BeanB.java
└── fieldInjection
    ├── BeanA.java
    └── BeanB.java

解决方案

原因说明

Spring Boot 2.6及以上版本默认禁用了循环依赖,即使Setter/Field注入这类原本Spring可处理的循环依赖场景,也会被默认拦截报错。

方案1:临时开启循环依赖允许(应急用)

在application.properties中添加配置:

spring.main.allow-circular-references=true

或在application.yml中添加:

spring:
  main:
    allow-circular-references: true

注意:此方案仅作为临时应急手段,Spring官方不推荐长期依赖,会增加代码维护复杂度。

方案2:重构代码打破循环依赖(推荐)

方式1:提取公共逻辑到独立Bean

将BeanA和BeanB互相依赖的业务逻辑,抽离为一个新的组件(比如CommonService),让BeanA和BeanB都依赖这个新组件,消除互相依赖关系。

示例:

@Component
public class CommonService {
    // 原BeanA和BeanB共享的逻辑
}

@Component
public class BeanA {
    private final CommonService commonService;

    public BeanA(CommonService commonService) {
        this.commonService = commonService;
    }
}

@Component
public class BeanB {
    private final CommonService commonService;

    public BeanB(CommonService commonService) {
        this.commonService = commonService;
    }
}

方式2:使用@Lazy延迟初始化依赖

给其中一个Bean的依赖添加@Lazy注解,让Spring在第一次实际使用该依赖时才初始化,而非启动阶段强制创建,从而避开循环依赖检查。

示例(Setter注入场景):

@Component
public class BeanA {
    private BeanB beanB;

    @Autowired
    public void setBeanB(@Lazy BeanB beanB) {
        this.beanB = beanB;
    }
}

示例(Field注入场景):

@Component
public class BeanA {
    @Autowired
    @Lazy
    BeanB beanB;
}

方式3:使用@DependsOn指定初始化顺序

通过@DependsOn注解强制指定Bean的初始化顺序,让其中一个Bean先完成初始化,再创建另一个Bean。

示例:

@Component
@DependsOn("beanB")
public class BeanA {
    private BeanB beanB;

    @Autowired
    public void setBeanB(BeanB beanB) {
        this.beanB = beanB;
    }
}

注意:此方式需确保业务逻辑允许该初始化顺序,避免出现未初始化的依赖调用问题。


内容的提问来源于stack exchange,提问作者clorzs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:26:08