Springboot循环依赖的解决方式

Springboot循环依赖的解决方式

起因

今天重构代码时,发现之前的代码结构完全混乱,没有按照MVC分层思想去编写,很多业务逻辑写在了controller中,导致引用的很多service和mapper依赖被注入到controller中。所以我准备将业务转移到service中,结果在改完代码准备debug启动的时候发现项目起不来了!springboot报错循环依赖,所以今天记录一下发生的原因和可用的解决方案。

原因

这个其实我也不好说,我自己写代码从来没有发现有循环依赖的问题,每个类确定好自己的职责,将方法正确的放入该类去引用bean一般就不会出现这种问题。。。这里我就描述一下循环依赖的产生吧,就是在容器启动过程准备bean的时候,会检测bean中是否注入了别的依赖,如果有就再去生成别的依赖对象注入到bean中,但是会发生这么一种情况,我有A,B两个@service,在A类中我通过注解引入B,然后再在B类中通过注解引入A,这个时候理论上就会无限产生A和B的实例,递归创建bean了属于是

下图我在一个Springboot项目中创建了A和B两个类,都加入了@Component注解并分别在其中注入另一个类

接下来启动该项目控制台报错:

根据提示可以很明显的看到,A依赖B,B依赖A导致循环

解决方案

配置文件解决

可以在配置文件中进行如下配置允许项目出现循环依赖:

yaml 复制代码
spring:
  main:
    allow-circular-references: true

但是不推荐这样,因为出现循环依赖应该是代码结构不规范导致的问题,如果有充足时间的话应该找出原因并优化,确保每个bean各司其职,一层一层依赖。

以下GPT回答:

bash 复制代码
为什么通常不推荐使用 allow-circular-references: true
代码可读性和可维护性:循环依赖使得代码结构复杂,增加了理解和维护的难度。
生命周期问题:当 Bean 之间存在循环依赖时,Spring 必须使用代理来处理这些问题,这可能导致 Bean 生命周期管理的复杂性。
性能影响:处理循环依赖会增加 Spring 创建 Bean 的开销,尤其是在大型应用中。
调试困难:循环依赖可能导致难以追踪的问题,尤其是当问题与特定环境或配置有关时

使用工具类获取bean

这种方式是使用SpringBeanUtil(一种可以获取Spring容器中bean的工具类,网上有很多)在业务代码中实时获取bean的方式,这种方式不需要在B类中注入A了,只需要在A类方法被调用之前获取到该bean即可

还有一种我设想的方案

这种不建议使用,原理是通过Springboot项目完全启动后(bean都生成完毕)执行的代码中使用SpringBeanUtil获取你想要的bean,然后通过set方法去注入所需要的bean实例,但是这种方式不太靠谱,因为项目完全启动后可能都接到请求了,如果在业务执行过程中你还没注入完毕的话很有可能导致NPE。。。

相关推荐
考虑考虑5 小时前
docker compose V2版本新属性
运维·后端·自动化运维
mldong6 小时前
一个 App,十三套后端:手机审批端 uni-jeeflow-app 开源了
java·架构
tqs_123457 小时前
MySQL RR隔离级别死锁|Gap间隙锁、临键锁,订单并发范围查询死锁根因方案
java
逆境不可逃7 小时前
Pi Agent 学习笔记:多个工具怎样并行执行
java
weixin_BYSJ19878 小时前
【计算机毕设】基于SpringBoot与Vue的文物保护档案管理系统08621
vue.js·spring boot·spring cloud·微服务·架构·django·课程设计
GreenTea8 小时前
7000 万 QPS、500 PB:OpenAI 如何用一个 Python 存储平台撑住 10 亿用户
后端·架构
Flynt8 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet8 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
GreenTea8 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
星云API技术支持8 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信