Spring中的循环依赖的解决办法

Spring中的循环依赖的解决办法

文章目录

  • Spring中的循环依赖的解决办法
    • 情形一:使用构造注入方式注入依赖
    • 情形二:使用Setter方式进行依赖注入
    • 情形三:使用延迟加载进行依赖注入
    • 情形四:使用第三方库进行依赖注入

先说明:推荐使用构造注入依赖的方式来解决循环依赖。还有不要把实例化与初始化搞混了,注意这两个的时机。

Spring中循环依赖的解决方案主要有以下几种:

情形一:使用构造注入方式注入依赖

  • 构造注入

构造注入不会循环依赖的原因在于,Spring在创建bean实例时,会立即解析依赖关系,并将依赖对象注入到bean实例中。例如,以下代码中,A类和B类之间存在循环依赖:

public class A {private B b;//步骤1.创建A的实例,未初始化 //步骤3获取到B的实例并对A进行初始化public A(B b) {this.b = b;}
}public class B {private A a;//步骤2创建B的实例未初始化 //步骤4获取到A的实例并对B进行初始化public B(A a) {this.a = a;}
}

构造注入的时候创建B的实例也需要先创建A的实例。但是,Spring在创建bean实例时,会使用一种特殊的机制来解决循环依赖的问题。

Spring在创建bean实例时,会使用循环依赖解析器(Circular Dependency Resolver)来解决循环依赖的问题。循环依赖解析器会按照一定的顺序来创建bean实例。对于构造注入,循环依赖解析器会按照如下顺序来创建bean实例:

1. 创建A的实例,但是A的实例还没有初始化。
2. 创建B的实例,但是B的实例还没有初始化。
3. 初始化A的实例,此时A的实例可以访问到B的实例。
4. 初始化B的实例,此时B的实例可以访问到A的实例。

流程大概是这样,就不会出现循环依赖的问题了。

情形二:使用Setter方式进行依赖注入

  • setter注入

相比之下,setter方法注入是在bean实例创建完成后再解析依赖关系,并将依赖对象注入到bean实例中。例如,以下代码中,A类和B类之间也存在循环依赖:

Java

public class A {private B b;//步骤1.他是先创建A的实例再创建B的实例(在调用A的Set方法之前肯定是已经有了A的实例) //步骤3.将B实例注入到A就会报错,因为A实例已经存在了public void setB(B b) {this.b = b;}
}public class B {private A a;//步骤2.在创建B的实例的时候A的实例已经存在了,可以直接获取到B的实例public void setA(A a) {this.a = a;}
}

当Spring创建A类的实例时,A类的实例已经创建完成了。但是,B类的实例还没有创建。Spring会在调用setB方法时,解析依赖关系,并将B类的实例注入到A类中。但是,由于A类的实例已经创建完成了,所以Spring无法创建B类的实例。这样,就出现了循环依赖的问题。

大概过程如下:

1. 创建A的实例
2. 将B注入到A中
3. 创建B的实例

因此,如果要避免循环依赖,建议使用构造注入。

情形三:使用延迟加载进行依赖注入

  • 延迟加载

延迟加载是指在bean实例真正需要使用依赖对象时才进行依赖注入。延迟加载可以避免循环依赖的问题,但可能会导致性能下降。

示例

Java

@Lazy
public class A {private B b;public A() {}public B getB() {if (b == null) {b = new B();}return b;}
}public class B {private A a;public B() {}public A getA() {if (a == null) {a = new A();}return a;}
}

上述代码中,A类和B类之间存在循环依赖。如果使用延迟加载,Spring会在A类或B类真正需要使用依赖对象时才进行依赖注入。这样就不会出现循环依赖的问题

情形四:使用第三方库进行依赖注入

  • 使用第三方库

Spring Boot提供了@AutowiredAnnotationBeanPostProcessor类,可以用于解决循环依赖的问题。该类会在bean实例创建完成后再解析依赖关系,并将依赖对象注入到bean实例中。

示例

Java

@AutowiredAnnotationBeanPostProcessor
public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean.getClass().getName().equals("com.example.A")) {A a = (A) bean;a.setB(new B());}return bean;}
}

上述代码中,A类和B类之间存在循环依赖。如果使用@AutowiredAnnotationBeanPostProcessor类,Spring会在A类或B类真正需要使用依赖对象时再进行依赖注入。这样就不会出现循环依赖的问题。

上面就是对循环依赖的解决方式分析,推荐使用构造方式注入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/162278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows上安装DBeaver

访问 DBeaver 的官方网站(https://dbeaver.io/)。 在主页上找到并点击 "Download" 或 "Get DBeaver Now"(获取 DBeaver)按钮。 您将看到不同的下载选项,选择适用于 Windows 的安装程序。通常为 …

重磅!2023年两院院士增选名单公布

中国科学院 关于公布2023年中国科学院院士增选当选院士名单的公告 根据《中国科学院院士章程》《中国科学院院士增选工作实施办法(试行)》等规定,2023年中国科学院选举产生了59名中国科学院院士。 现予公布。 中国科学院 2023年11月22日…

设计模式——结构型模式

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更…

机器学习算法(1)——简单线性回归

一、说明 在在这篇文章中,我们将学习我们的第一个机器学习算法,称为简单线性回归。这是一个重要的算法,因为当您可能正在学习第一个神经网络(称为人工神经网络)时,在此算法中学习的技术也适用于深度学习。我…

毕业设计ASP.NET 1400动漫公司网站【程序源码+文档+调试运行】

摘要 本系统将实现一个动漫公司网站,包括前台用户模块和后台管理员模块。前台用户模块主要包括最新动漫、注册登录、公司简介、公司新闻、动漫中心、联系我们和会员中心等功能。后台管理员模块包括用户管理、公司简介管理、公司新闻管理、动漫类别管理、动漫管理、…

加工车间污水处理设备有哪些

在加工车间中,污水处理设备是至关重要的一部分。它们的功能是将污水进行处理,确保其达到符合环保标准的水质要求。以下是一些常见的加工车间污水处理设备: 1.初级沉淀池:初级沉淀池是最基本的污水处理设备之一。它通过重力作用将…

阿里云服务器ECS产品知识及购买和使用常见问题及答案汇总

本文总结了阿里云用户在购买和使用阿里云服务器中的一些常见的问题,包括什么是云服务器ECS,特性与优势,应用场景,基本概念,使用限制等众多问题,让您全方位了解阿里云服务器,并根据自己的需求选择…

Qt pro常用宏

RC_ICONS IStudio.icoCONFIG no_debug_release # 不会生成debug 和 release 文件目录 DESTDIR $$PWD/../bin # 指定编译最终文件的生成路径 OBJECTS_DIR $$PWD/temp/obj # obj中间文件存放路径 MOC_DIR $$PWD/temp/moc # moc中间文件…

百战python01-初识python_turtle绘图

文章目录 简介练习1.简易的进度条学习使用turtle在屏幕上绘制图形注:需要对python有基本了解,可查看本作者python基础专栏,有任何问题欢迎私信或评论(本专栏每章内容都将不定期进行内容扩充与更新) 简介 python简介及方向+pycharm安装使用请转 练习 注:尝试练习。了解…

Windows系统中curl和wget命令下载说明

前言 当需要在命令行中发送 HTTP 请求时,常用的工具有 curl 和 wget。它们可以帮助你下载文件,发送 POST 或 GET 请求,以及检查网页内容等。 curl: curl 是一个功能强大的命令行工具,支持多种协议(例如 HTTP、HTTPS、…

常见树种(贵州省):010任豆、漆树、椿树、伯乐树、栾树、楸树、橡胶树、盐肤木、吴茱萸、黄柏

摘要:本专栏树种介绍图片来源于PPBC中国植物图像库(下附网址),本文整理仅做交流学习使用,同时便于查找,如有侵权请联系删除。 图片网址:PPBC中国植物图像库——最大的植物分类图片库 一、任豆 …

趋势解读:TikTok独创的社交语言是如何演变的

在数字时代的浪潮中,社交媒体平台成为人们传递信息、表达创意和建立社交联系的重要场所。而在这众多社交平台中,TikTok以其独特的社交语言和创新的内容形式,迅速吸引了全球数以亿计的用户。本文将深入探讨TikTok的社交语言是如何独创并演变的…

中年人怎么发展?持续发展?

现在ai这么火,就像当年的xxx,如果没有抓住,会xxx吗? 为了ai,多学学python也是也是好的啊。 在学习之余,还是想做做自媒体的。不求马上赚到钱。我的想法是,现在每天下班回家都是刷刷抖音&#…

win10戴尔电脑安装操作系统遇到的问题MBR分区表只能安装GPT磁盘

首先按F2启动boot管理界面 调整启动盘的启动顺序,这里启动U盘为第一顺序。 第一步 选择安装程序的磁盘 第二步 转换磁盘为GPT磁盘 一般出现 磁盘0和1,说明存在两个盘 ,这里两个盘不是说的是C盘和D盘的问题,而是在物理上实际存在…

easyExcel实现分批导入,动态表头分批导出,以及导出表格样式设置

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency> 一&#xff0c;分批导入 1.首先配置表格头映射类 Getter Setter EqualsAndHashCode public class …

YOLOV5标注训练自己的数据全流程教程

概述 yolo在目标检测领域是非常有代表性的模型&#xff0c;它速度快识别效果也很精准&#xff0c;是实时检测模型中应用最广泛的。yolo的原理和代码是很容易获得的&#xff0c;且有各式各样的教程&#xff0c;但是模型怎么使用的教程相对比较少。本文讲解如何使用yolov5模型训…

Linux运行jmeter报错java.sql.SQLException:Cannot create PoolableConnectionFactory

在性能测试过程中遇见1个问题&#xff0c;终于解决了&#xff0c;具体问题如下。 问题 在windows电脑写jmeter脚本连接数据库连接成功 然后把该脚本放到Linux服务器上面&#xff0c;并把jmeter mysql驱动放到服务器上面&#xff0c;修改jmeter的mysql驱动路径信息 注意&…

第十三章 : Spring Boot 日志记录脱敏

第十三章 : Spring Boot 日志记录脱敏 前言 本章重点:介绍secure-ext-spring-boot-starter 如何引入以及敏感数据脱敏,打印日志过程中自动脱敏,且支持手机号、邮箱、身份证号、住址、中文名、座机号、银行卡、自定义等多种类型的脱敏。 基于Spring boot 2.3.2.RELEASE 背景…

【快速解决】实验一:模拟实现进程的创建《操作系统上机》实验报告

目录 实验要求 正文开始 ​编辑 难点讲解 结语 实验要求 实验一&#xff1a;进程的创建 一、实验项目类型&#xff1a;设计型 二、实验目的和要求 加深对进程概念的理解&#xff0c;熟悉PCB的组织&#xff0c;深入了解创建进程的一般过程&#xff0c;掌握用队列组织进程的…

数据库系统之常用数据库你用过几个?

MySQL 开发厂商&#xff1a;AB公司——>Sun公司——>甲骨文公司 最新版本&#xff1a;5.7.43、8.0.34 发行方式: 社区版&#xff08;MySQL Community Server&#xff09; 免费&#xff0c;MySQL不提供任何技术支持 商业版&#xff08;MySQL Enterprise Edition&#xff0…