Springboot微服务整合缓存的时候报循环依赖的错误 两种解决方案

简介: Springboot微服务整合缓存的时候报循环依赖的错误 两种解决方案

错误再现

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2024-06-17 16:52:41.008 ERROR 20544 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 
 
***************************
APPLICATION FAILED TO START
***************************
 
Description:
 
The dependencies of some of the beans in the application context form a cycle:
 
┌─────┐
|  redisAutoInit (field protected com.alicp.jetcache.anno.support.ConfigProvider com.alicp.jetcache.autoconfigure.AbstractCacheAutoInit.configProvider)
↑     ↓
|  springConfigProvider
└─────┘
 
 
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.

简介

当应用程序上下文中的一些bean的依赖关系形成循环时,意味着这些bean之间存在循环依赖关系。换句话说,Bean A依赖于Bean B,同时Bean B又依赖于Bean A,形成一个闭环。这种情况通常发生在使用依赖注入框架(如Spring)管理bean之间的依赖关系时。

典型的循环依赖问题

循环依赖可能导致以下问题:

  1. 初始化问题:如果两个或多个bean彼此依赖,框架可能无法解析哪个bean应该先初始化,从而导致初始化失败或延迟。
  2. 运行时异常:常见的错误是BeanCurrentlyInCreationException,它表明Spring在尝试创建bean实例时检测到循环依赖。
  3. 代码的可维护性降低:循环依赖增加了组件之间的耦合性,使代码更难理解和维护。这可能使代码变得更脆弱,难以修改或测试。

如何处理循环依赖

在Spring中,有几种处理循环依赖的方法:

  1. 构造函数注入:首选使用构造函数注入而不是setter方法注入。构造函数注入有助于打破循环,因为所有依赖关系在bean实例化时都会被解析。
  2. 延迟注入:使用@Lazy注解延迟注入依赖关系。这可以推迟直到需要时才注入bean,从而可能打破循环。
  3. 方法注入:在某些情况下,可以使用方法注入并在方法上使用@Autowired注解。这种方法也可以帮助打破循环依赖。
  4. Aware接口:对于无法通过直接依赖注入解决的情况,可以考虑使用Aware接口,如ApplicationContextAwareBeanFactoryAware
  5. 使用代理解决:在某些情况下,Spring可以通过运行时代理来管理循环依赖。

最佳实践

  • 避免循环依赖:尽量避免设计中出现循环依赖。循环依赖通常表明设计可能需要重新审视,以增强模块化和降低耦合度。
  • 使用构造函数注入:构造函数注入通常是处理循环依赖的最佳实践,因为它使依赖关系更明确,并且有助于避免初始化顺序问题。
  • 进行代码审查和测试:对可能存在循环依赖的代码进行彻底的代码审查和测试,以尽早发现并解决问题。

处理循环依赖需要综合考虑应用程序的架构和设计。Spring提供了多种机制来处理这些情况,但理想情况下,应该尽量设计具有清晰依赖关系且避免循环依赖的代码结构。

两种解决方案

解决方案一

降低spingboot的版本

在pom.XML文件中去修改

<properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>

解决方案二

在yml配置文件里配置属性

配置spring框架的属性

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
      username: root
      password: 123456
 
  devtools:
    restart:
      # 设置不参与热部署的文件或文件夹
      exclude: static/**,public/**,config/application.yml
 
  main:
    allow-circular-references: true

主要是这一行

这段配置看起来像是针对某种配置文件或框架的设置,其中 allow-circular-references: true 的意思是允许循环依赖。

在某些依赖注入框架(比如Spring)中,默认情况下是不允许循环依赖的,因为循环依赖可能导致初始化顺序问题或者在解析依赖关系时产生死锁。但有时候,循环依赖是不可避免的或者设计上是合理的,因此框架允许用户显式地设置来解决这类问题。

解释:

  • allow-circular-references: true:这个配置告诉框架或配置文件,允许在应用程序上下文中出现循环依赖。这意味着,如果两个或多个bean彼此依赖,并且形成了循环依赖,框架会尝试解决这些依赖关系而不会报错。

注意事项:

  • 慎重使用:虽然允许循环依赖可以解决特定情况下的问题,但过度依赖循环依赖可能导致代码难以理解和维护。
  • 替代解决方案:通常情况下,尝试避免设计上需要循环依赖的情况是更好的选择。可以考虑通过重构或者重新设计来减少循环依赖的发生。
  • 框架特定性:具体实现可能会有所不同,需要查阅相应框架的文档以了解详细的配置方法和影响。

总之,这种配置通常用于在特定场景下解决循环依赖问题,但使用时需要谨慎考虑其长期维护和代码质量的影响。

  main:
    allow-circular-references: true

成功启动

目录
相关文章
|
4天前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
11 0
|
2月前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
62 2
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
124 3
|
4月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
5月前
|
数据库 开发者 微服务
微服务架构下的数据一致性挑战与解决方案
在当今的软件开发领域,微服务架构因其灵活性和可扩展性而受到广泛青睐。然而,这种架构风格也带来了数据一致性的复杂问题。本文将深入探讨微服务环境中数据一致性面临的挑战,并提出一系列解决策略。我们将以实际案例分析如何应用这些策略,并讨论它们在不同场景下的利弊。文章旨在为后端开发者提供一套实用工具和方法,帮助他们在设计和实现微服务时确保数据一致性。
152 0
|
3月前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
209 24
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
2月前
|
Java Maven Spring
SpringBoot项目创建失败或无法启动,启动报错时的常见问题及解决方案
文章列举了在IDEA中创建Spring Boot项目时可能遇到的常见问题及其解决方案,如项目不被识别为Maven项目、依赖未找到或报红、JDK版本不一致和POM文件中的Jar包下载失败等问题。
243 0
SpringBoot项目创建失败或无法启动,启动报错时的常见问题及解决方案
|
3月前
|
前端开发 Java Spring
【非降版本解决】高版本Spring boot Swagger 报错解决方案
【非降版本解决】高版本Spring boot Swagger 报错解决方案
|
2月前
|
缓存 NoSQL 关系型数据库
缓存穿透以及解决方案
缓存穿透以及解决方案
35 0
|
4月前
|
缓存 NoSQL 数据库
go-zero微服务实战系列(五、缓存代码怎么写)
go-zero微服务实战系列(五、缓存代码怎么写)