【Spring Boot】Spring Boot解决循环依赖

循环依赖问题概述

循环依赖是指两个或多个组件相互依赖,形成闭环。例如,Bean A 依赖 Bean B,而 Bean B 又依赖 Bean A。Spring Boot 默认情况下会抛出 BeanCurrentlyInCreationException 异常。

解决方法

使用构造函数注入 + @Lazy

通过 @Lazy 注解延迟初始化其中一个 Bean,打破初始化时的循环依赖链。

@Service
public class ServiceA {
    private final ServiceB serviceB;

    @Autowired
    public ServiceA(@Lazy ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

@Service
public class ServiceB {
    private final ServiceA serviceA;

    @Autowired
    public ServiceB(ServiceA serviceA) {
        this.serviceA = serviceA;
    }
}

改为 Setter/Field 注入

Spring 的三级缓存机制可以处理 Setter 或 Field 注入的循环依赖,但不支持构造函数注入的循环依赖。

@Service
public class ServiceA {
    @Autowired
    private ServiceB serviceB;
}

@Service
public class ServiceB {
    @Autowired
    private ServiceA serviceA;
}

重构代码设计

从根本上避免循环依赖,通常更推荐:

  • 提取公共逻辑到第三个 Bean
  • 使用事件驱动模式(如 ApplicationEventPublisher
  • 依赖接口而非具体实现
调整 Bean 加载顺序

通过 @DependsOn 强制指定初始化顺序:

@Service
@DependsOn("serviceB")
public class ServiceA {
    @Autowired
    private ServiceB serviceB;
}

@Service
public class ServiceB {
    @Autowired
    private ServiceA serviceA;
}

注意事项

  • 构造函数注入是 Spring 官方推荐的方式,但需结合 @Lazy 解决循环依赖
  • 循环依赖可能暴露设计问题,应优先考虑重构
  • Spring 2.6+ 版本默认禁止循环依赖,可通过配置开启:
    spring.main.allow-circular-references=true
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值