首页 > 其他分享 >SpringBoot循环依赖

SpringBoot循环依赖

时间:2024-10-20 23:46:18浏览次数:3  
标签:依赖 SpringBoot Spring 构造 Bean 循环 注入

在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;

    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }
}

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

标签:依赖,SpringBoot,Spring,构造,Bean,循环,注入
From: https://blog.csdn.net/sdg_advance/article/details/143101346

相关文章

  • Spring依赖注入
    依赖注入(DependencyInjection,DI)**是软件设计中的一种设计模式,用来实现对象之间的解耦。在这种模式下,对象不需要自己创建其依赖的对象,而是将所需的依赖通过外部注入到对象中。这种方式使得代码更加模块化、灵活且容易测试。在Spring框架中,依赖注入是核心功能之一,Spring通过......
  • Springboot抗灾援助系统58085(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,灾害类型,灾害知识,抗灾技巧,援助项目,捐款类型,援助信息,需求信息,募捐活动,企业合作,积分商品,积分兑换开题报告内容一、研究背景与意义随着全球气候变......
  • Springboot抗疫资源管理系统vc4s0(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,志愿者,健康打卡,物资信息,分类,分配信息,物资入库,申请任务,分配任务,志愿者打卡开题报告内容研究背景近年来,全球公共卫生事件的频发,特别是新冠疫情的爆......
  • Springboot考勤管理系统.0p420(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表学生,教师,学习资料,考勤信息,学生打卡,请假信息开题报告内容一、研究背景与意义随着信息技术的快速发展,企业和学校对考勤管理的需求日益提高。传统的考勤方式,......
  • 测开必备-java基础-for、while和do-while循环使用场景
    在编程中,选择使用for循环、while循环还是do-while循环,主要取决于你的具体需求和代码逻辑。下面我们来详细讨论一下这三种循环的使用场景。for循环的使用场景for循环通常用于已知循环次数的场景,特别是当你需要遍历数组、集合或执行固定次数的迭代时。for循环的语法结构清晰地定义......
  • Springboot启动失败问题:Application run failed(jdk原因)
    以下代码报错ErrorstartingApplicationContext.Todisplaytheconditionsreportre-runyourapplicationwith'debug'enabled.2024-10-1921:56:55.234ERROR16584---[main]o.s.boot.SpringApplication:Applicationrunfailed......
  • springboot3.0自动配置
    目标本文主要介绍springboot3.0是如何创建一个可以进行自动配置的jar包的自动配置的定义是,一个jar包里面定义了一些spring的bean,当导入这个jar包的时候会自动将这些bean导入进去方法创建AutoConfiguration.imports文件创建目录META-INF/spring/org.springframework.boot.a......
  • 时间序列预测(六)——循环神经网络(RNN)
    目录一、RNN的基本原理1、正向传播(ForwardPass):2、计算损失(LossCalculation)3、反向传播——反向传播通过时间(BackpropagationThroughTime,BPTT)4、梯度更新:二、RNN的常用结构 1、N——N结构2、N——1结构3、1——N结构4、N——M结构(Encoder-Decoder,也称Seq2Seq)三......
  • mysql对结果集进行遍历(mysql双重for循环如何写)
    原文链接:mysql对结果集进行遍历(mysql双重for循环如何写)–每天进步一点点0.背景有这么一个需求:对以下的类型结果集进行更新。更新的原则是type为c的currentValue的值=(type为b的currentValue)/((type为b的currentValue)+(type为a的currentValue))*100。上面这个需求......
  • SpringBoot使用默认的日志logback(2)—自定义配置+控制台输出sql语句
    原文链接:SpringBoot使用默认的日志logback(2)—自定义配置+控制台输出sql语句–每天进步一点点上一篇文章中简单介绍了springboot通过系统配置的方式配置日志:SpringBoot使用默认的日志logback(1)—系统配置这篇文章简单介绍一下日志的自定义配置。1.自定义配置springboot......