如何解决SpringBoot2.6及之后版本取消了循环依赖的支持问题

 更新时间:2024年10月29日 11:10:59   作者:天空中那座城  
循环依赖指的是两个或者多个bean之间相互依赖,形成一个闭环,SpringBoot从2.6.0开始默认不允许出现Bean循环引用,解决方案包括在全局配置文件设置允许循环引用存在、在SpringApplicationBuilder添加设置允许循环引用、构造器注入

1、问题

循环依赖指的是两个或者多个bean之间相互依赖,形成一个闭环。直接表现为两个service层互相调用对方。

此时会遇到以下问题:

2、报错

当启动项目时,可能出现程序不能启动的情况,查看调试日志,会提示:

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

如下图所示:

根据上述代码片段,应用程序存在以下循环依赖:

1. adminBorrowInfoController 依赖 borrowInfoServiceImpl

2. borrowInfoServiceImpl 依赖 lendServiceImpl

3. lendServiceImpl 依赖 lendItemServiceImpl

4. lendItemServiceImpl 又反过来依赖 lendServiceImpl

这样就形成了一个循环依赖的场景。

原因是SpringBoot 从 2.6.0 开始默认不允许出现 Bean 循环引用。而且这个是在Bean 定义上也就是类上就不允许出现循环引用。

3、解决方案

第1种、在全局配置文件设置允许循环引用存在

升级到Spring Boot 2.7及以上版本,可以通过spring.main.allow-circular-references=true配置属性明确开启循环依赖支持。

但我用的2.6.11也可以哦,2.6以上的可以试试。

spring:
  main:
    allow-circular-references:true

第2种、在SpringApplicationBuilder 添加设置允许循环引用

使用SpringApplicationBuilder来启动Spring Boot应用,并通过allowCircularReferences(true)方法开启了循环依赖支持。

public static void main(String[] args) {
  new SpringApplicationBuilder(DemoApplication.class).allowCircularReferences(true).run(args);
}

第N种、还有很多种供大家了解使用

1. 构造器注入

  • 在类中定义构造器,添加需要依赖的类作为参数
  • 使用@Autowired注解构造器
  • Spring会先实例化依赖类,然后通过构造器注入

2. @Lazy

  • 在导致循环依赖的Bean上添加@Lazy注解
  • Spring会延迟初始化这些Bean,先完成非Lazy的Bean初始化
  • 然后再通过setter注入完成Lazy Bean的初始化

3. ObjectFactory

  • 定义ObjectFactory属性,类型为对应类的ObjectFactory
  • Spring会代理注入ObjectFactory,获取对象时才初始化目标Bean

4. 服务定位器

  • 定义一个统一的服务定位器类
  • Bean直接从定位器获取依赖对象,而不是注入依赖

5. 合并类

  • 将互相依赖的类合并为一个类,避免相互依赖

6. 事件回调

  • 使用事件或者回调方式实现解耦
  • 一个类通过事件通知另一个类执行操作,而不是直接调用

7. 接口编程

  • 类依赖接口,不依赖具体实现
  • 具体实现通过setter注入接口

以上是一些主要的具体实现步骤,可以根据实际情况选择适合的方案。

总体上,出现循环依赖通常意味着系统设计需要优化和解耦,需要重新梳理服务的职责和依赖关系,减少不必要的互相依赖,以提高内聚性和可维护性。

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java 域对象共享数据的实现

    java 域对象共享数据的实现

    本文主要介绍了java 域对象共享数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • java运行时数据区域和类结构详解

    java运行时数据区域和类结构详解

    这篇文章主要介绍了java运行时数据区域和类结构,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • SpringBoot+log4j2.xml使用application.yml属性值问题

    SpringBoot+log4j2.xml使用application.yml属性值问题

    这篇文章主要介绍了SpringBoot+log4j2.xml使用application.yml属性值问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Post请求参数是数组或者List时的请求处理方式

    Post请求参数是数组或者List时的请求处理方式

    这篇文章主要介绍了Post请求参数是数组或者List时的请求处理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • 浅析java消息摘要与数字签名

    浅析java消息摘要与数字签名

    这篇文章给大家分析了关于java消息摘要与数字签名的相关知识点内容,有兴趣的朋友们可以学习下。
    2018-08-08
  • Java 调用Restful API接口的几种方式(HTTPS)

    Java 调用Restful API接口的几种方式(HTTPS)

    这篇文章主要介绍了Java 调用Restful API接口的几种方式(HTTPS),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • java Spring 5 新特性函数式Web框架详细介绍

    java Spring 5 新特性函数式Web框架详细介绍

    正如昨天Juergen博客中所提到的,Spring 5.0的第二个里程碑是引入了一个新的函数式web框架。在这篇文章中,我们将给出关于这个框架的更多信息,,需要的朋友可以参考下
    2016-12-12
  • Java ByteBuffer网络编程用法实例解析

    Java ByteBuffer网络编程用法实例解析

    这篇文章主要介绍了Java ByteBuffer网络编程用法实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • FileUtils扩展readURLtoString读取url内容

    FileUtils扩展readURLtoString读取url内容

    这篇文章主要介绍了FileUtils扩展readURLtoString使用其支持读取URL内容为String,支持带POST传大量参数,大家参考使用吧
    2014-01-01
  • IntelliJ IDEA优化配置的实现

    IntelliJ IDEA优化配置的实现

    这篇文章主要介绍了IntelliJ IDEA优化配置的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论