SpringBoot循环依赖的6种解决方案

您所在的位置:网站首页 公式循环引用怎么解决 SpringBoot循环依赖的6种解决方案

SpringBoot循环依赖的6种解决方案

2024-07-14 02:50:36| 来源: 网络整理| 查看: 265

在Spring Boot的开发中循环依赖是一个常见的问题,两个或多个类之间存在彼此依赖的情况,形成一个循环依赖链,在2.6.0之前,Spring Boot会自动处理循环依赖的问题,而2.6.0版本以上开始检查循环依赖,存在该问题则会报错。本文将给大家说说Spring Boot循环依赖的原理和解决方案。

循环依赖定义

当一个类在初始化时需要另一个类的实例,而另一个类又需要第一个类的实例时,就会出现循环依赖问题。这会导致应用程序无法正确地初始化和运行,因为Spring Boot 无法处理这种循环依赖关系。在启动时程序就会报错。

循环依赖问题的示例

UserService 类注入VipService 类,VipService 类注入UserService 类,就会发生循环依赖的问题。

@Service public class UserService { @Resource private VipService vipService; } @Service public class VipService { @Resource private UserService userService; }

错误

现在,2.6.0 这个版本已经默认禁止 Bean 之间的循环引用, 则基于上面的代码,会报错:

错误提示

解决方法

构造函数注入: 在构造函数中注入依赖项,而不是在属性中注入。

Setter注入: 使用setter方法注入依赖项,而不是在构造函数中注入。

延迟注入: 使用@Lazy注解延迟加载依赖项。

@Autowired注解的required属性: 将required属性设置为false,以避免出现循环依赖问题。

@DependsOn注解: 使用@DependsOn注解指定依赖项的加载顺序,以避免出现循环依赖问题。

修改配置让SpringBoot 回到2.6以前的自动检测循环依赖。

假设有以下两个类:

public class A { private B b; public A() { // ... } public void setB(B b) { this.b = b; } } public class B { private A a; public B() { // ... } public void setA(A a) { this.a = a; } } 构造函数注入 public class A { private B b; public A(B b) { this.b = b; } } public class B { private A a; public B(A a) { this.a = a; } }

这样,在创建 A 实例时,只需要将 B 实例传递给 A 的构造函数即可,不需要再通过 setter 方法将 B 实例注入到 A 中。同理,在创建 B 实例时,只需要将 A 实例传递给 B 的构造函数即可,不需要再通过 setter 方法将 A 实例注入到 B 中。这样可以避免循环依赖。

延迟注入

为了解决这个问题,可以使用@Lazy注解,将类A或类B中的其中一个延迟加载。

例如,我们可以在类A中使用@Lazy注解,将类A延迟加载,这样在启动应用程序时,Spring容器不会立即加载类A,而是在需要使用类A的时候才会进行加载。这样就避免了循环依赖的问题。

@Component public class A { private final B b; public A(@Lazy B b) { this.b = b; } //... } @Component public class B { private final A a; public B(A a) { this.a = a; } //... } 接口隔离的案例

假设有两个类A和B,它们之间存在循环依赖:

public class A { private final B b; public A(B b) { this.b = b; } } public class B { private final A a; public B(A a) { this.a = a; } }

这时候,如果直接在Spring Boot中注入A和B,就会出现循环依赖的问题。为了解决这个问题,可以使用接口隔离。

首先,定义一个接口,包含A和B类中需要使用的方法:

public interface ComonService { void doThings(); }

然后,在A和B类中分别注入Service接口:

public class A { private final ComonService comonService ; public A(ComonService comonService ) { this.comonService = comonService ; } } public class B { private final ComonService service; public B(ComonService comonService ) { this.comonService = comonService ; } }

最后,在Spring Boot中注入Service实现类:

@Service public class ComonServiceImpl implements ComonService { private final A a; private final B b; public ComonServiceImpl (A a, B b) { this.a = a; this.b = b; } @Override public void doThings() { // ... } }

通过这种方式,A和B类不再直接依赖于彼此,而是依赖于同一个接口。同时,Spring Boot也能够正确地注入A、B和ComonServiceImpl ,避免了循环依赖的问题。

修改配置文件

spring:

main:

allow-circular-references:true

结束语

综上所述,Spring Boot循环依赖是一个需要注意和解决的问题。通过对循环依赖的原理和解决方案的深入理解,我们可以更好地避免循环依赖带来的问题,提高软件的质量和可维护性。

参考文章地址1:百度安全验证



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭