当前位置: 首页 > news >正文

SpringBoot循环依赖

在Spring Boot(以及Spring框架)中,循环依赖是指两个或多个Bean互相依赖,导致Spring在创建这些Bean时无法正常进行依赖注入。例如,假设有两个类ABA依赖于B,而B又依赖于A。在这种情况下,Spring框架在尝试实例化其中一个Bean时,会发现另一个Bean尚未创建,从而产生循环依赖问题。

循环依赖的类型

循环依赖可以分为构造器循环依赖属性循环依赖两种:

构造器循环依赖

当两个或多个Bean通过构造器参数相互依赖时,就会出现构造器循环依赖。这种依赖情况是Spring无法处理的,因为在构造器注入阶段,Spring必须一次性完成所有Bean的实例化,因此无法解决构造器的循环依赖。

属性循环依赖(Setter循环依赖):

当Bean通过属性注入(Setter注入)方式相互依赖时,Spring可以通过创建Bean的半成品(只创建实例但不完全初始化)来解决这个问题。具体来说,Spring首先会实例化一个Bean(不调用其依赖的Setter方法),然后实例化另一个Bean,最后将依赖的属性注入回去。

Spring 如何处理循环依赖

单例Bean(Singleton Scope)

Spring默认是允许单例Bean的属性循环依赖的。它的解决机制是:Spring在创建Bean时,会先创建Bean的一个未完成的实例(放入一级缓存),即创建对象但不完全初始化(还没有设置属性)。然后,它会将这个未初始化的对象放入一个三级缓存,供后续可能需要的依赖查找使用。如果在实例化其他Bean时需要依赖这个Bean,Spring会通过三级缓存获取未完成的实例,并继续完成注入过程。

构造器注入

Spring无法处理构造器的循环依赖,因为在构造器注入时,Bean必须在构造函数中完全初始化。由于无法在构造函数执行之前就创建依赖对象,Spring在这种情况下会抛出BeanCurrentlyInCreationException

非单例Bean(Prototype Scope)

Spring无法解决非单例Bean的循环依赖。在Prototype作用域下,Spring不管理Bean的生命周期,因此无法像单例Bean一样进行缓存处理。此时,如果出现循环依赖,会抛出异常。

解决循环依赖的方法

重构代码,消除循环依赖:这是最根本的解决方式。检查是否有设计上的问题导致了循环依赖,尽量将依赖解耦。可以通过引入中介类、事件机制或者工厂模式等方式重构代码。

使用Setter注入:如果循环依赖无法避免,可以尽量使用Setter注入而不是构造器注入,因为Spring能够处理属性级别的循环依赖。

使用@Lazy注解:对于某些Bean依赖,可以使用@Lazy注解,告诉Spring在需要时才初始化该Bean,从而打破循环依赖。例如:

@Service
public class A {private final B b;@Autowiredpublic A(@Lazy B b) {this.b = b;}
}

使用ApplicationContextAware:如果需要通过构造器注入的方式解决循环依赖,可以通过实现ApplicationContextAware接口,在运行时手动获取依赖Bean。

http://www.lryc.cn/news/468053.html

相关文章:

  • 一道面试题:为什么要使用Docker?
  • 类的创建、构造器、实例属性、实例方法
  • js读取.txt文件内容
  • 【AscendC算子开发】笔记2 算子高级开发和调试调优
  • vscode连接keil-5 开发STM32 程序
  • 数据结构深度优先搜索遍历连通图+非连通图(C语言代码+遍历+终端输入内容)
  • 信息安全工程师(55)网络安全漏洞概述
  • member access within null pointer of type ‘ListNode‘
  • UE5蓝图中整理节点的方法
  • 01,http 协议
  • 在 typescript 中,如何封装一个 class 类来接收接口的响应数据
  • 力扣周赛第420场 中等 3325.字符至少出现k次的子字符串 I
  • 【Spring框架】Spring核心思想IoC以及依赖注入DI详解
  • Java项目-基于springboot框架的智慧外贸系统项目实战(附源码+文档)
  • Python程序控制结构 if语句详解
  • 【ppq install】
  • 3DGS相关方法conda环境配置
  • python画图|曲线动态输出
  • 电子商务类型
  • vue elementui el-table实现增加行,行内编辑修改
  • 1. Redis简介与安装
  • Redis的持久化存储和集群管理操作
  • Auto-encoder(自编码器)
  • Vue+sortable+el-table表格排序使用指南
  • 表数据删一半,为什么表文件大小不变?
  • MoCoOp: Mixture of Prompt Learning for Vision Language Models
  • YOLOv8 onnx 部署
  • 在文件里引用目录文件下的静态资源图片不显示
  • vue使用 jsplumb 生成流程图
  • 攻坚金融关键业务系统,OceanBase亮相2024金融科技大会