Spring中循环依赖解决方案

news2024/11/18 19:31:29

循环依赖

 循环依赖是Spring框架中常见的问题之一,当两个或多个类相互引用对方时,就会出现循环依赖的情况。这种情况下,Spring框架无法确定哪个类应该先实例化和初始化,从而导致异常。常见的解决方法有:构造函数注入、setter方法注入、静态工厂方法注入以及使用第三方库等

本次使用版本:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.0</version>
    <relativePath/>
</parent>

案例

public interface ServiceA {
}

public interface ServiceB {
}

@Service
public class ServiceAImpl implements ServiceA {
    private ServiceB serviceB;

    public ServiceAImpl(ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

@Service
public class ServiceBImpl implements ServiceB {
    private ServiceA serviceA;

    public ServiceBImpl(ServiceA serviceA) {
        this.serviceA = serviceA;
    }
}

在这里插入图片描述

解决方法

1.重新设计

当有一个循环依赖,很可能是有一个设计问题并且各责任没有得到很好的分离。应该尽量正确地重新设计组件,以便它们的层次是精心设计的,也没有必要循环依赖。

如果不能重新设计组件(可能有很多的原因:遗留代码,已经被测试并不能修改代码,没有足够的时间或资源来完全重新设计…),但有一些变通方法来解决这个问题。

2.@Lazy

 解决Spring 循环依赖的一个简单方法就是对一个Bean使用延时加载。也就是说:这个Bean并没有完全的初始化完,实际上他注入的是一个代理,只有当他首次被使用的时候才会被完全的初始化。

@Service
public class ServiceAImpl implements ServiceA {
    private ServiceB serviceB;

    public ServiceAImpl(@Lazy ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

3.Setter/Field 注入

简单地说,你对你需要注入的bean是使用setter注入(或字段注入),而不是构造函数注入。通过这种方式创建Bean,实际上它此时的依赖并没有被注入,只有在你须要的时候他才会被注入进来。

@Service
public class ServiceAImpl implements ServiceA {
    private ServiceB serviceB;

    @Autowired
    public void setServiceB(ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

SpringBoot 2.6.x不推荐使用循环依赖,最简单的方式是在全局配置文件中允许循环引用存在,此属性默认值为false,显示声明为true,可回避项目启动时控制台循环引用异常。

spring:
  main:
    allow-circular-references: true

4.@PostConstruct

打破循环的另一种方式是:在要注入的属性(该属性是一个bean)上使用 @Autowired ,并使用@PostConstruct 标注在另一个方法,且该方法里设置对其他的依赖。

@Service
public class ServiceAImpl implements ServiceA {
    @Autowired
    private ServiceB serviceB;

    @PostConstruct
    public void init() {
        System.out.println(serviceB);
        serviceB.setServiceA(this);
    }
}

@Service
public class ServiceBImpl implements ServiceB {
    private ServiceA serviceA;

    public void setServiceA(ServiceA serviceA) {
        System.out.println(serviceA);
        this.serviceA = serviceA;
    }
}

总结:

方式依赖情况注入方式能够解决循环依赖
情况一AB相互依赖均采用setter方式
情况二AB相互依赖均采用构造器方式不能
情况三AB相互依赖A中注入B采用setter,B中注入A采用构造器
情况四AB相互依赖A中注入B采用构造器,B中注入A采用setter不能
情况五AB相互依赖A中注入B采用@Autowired,B中注入A采用@PostConstruct + setter
情况六AB相互依赖A中注入B采用@PostConstruct + setter,B中注入A采用@Autowired

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

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

相关文章

STM32单片机通过串口烧录hex程序

我之前买过一个STM32最小程序单片机&#xff0c;原来下载51单片机都是使用串口方式&#xff0c;这里也通过串口方式烧录STM32单片机&#xff0c;还需要借助一个USB TO TTL工具。 USB TO TTL工具类似一个U盘工具&#xff0c;只不过它另一端是接线&#xff0c;一般电脑会自动安装…

C++入门篇9---list

list是带头双向循环链表 一、list的相关接口及其功能 1. 构造函数 函数声明功能说明list(size_type n,const value_type& valvalue_type())构造的list中包含n个值为val的元素list()构造空的listlist(const list& x)拷贝构造list(InputIterator first, InputIterator…

推荐系统系列之推荐系统概览(上)

在当今信息化高速发展的时代&#xff0c;推荐系统是一个热门的话题和技术领域&#xff0c;一些云厂商也提供了推荐系统的SaaS服务比如亚马逊云科技的 Amazon Personalize 来解决客户从无到有迅速构建推荐系统的痛点和难点。在我们的日常生活中&#xff0c;推荐系统随处可见&…

论文阅读 - Understanding Diffusion Models: A Unified Perspective

文章目录 1 概述2 背景知识2.1 直观的例子2.2 Evidence Lower Bound(ELBO)2.3 Variational Autoencoders(VAE)2.4 Hierachical Variational Autoencoders(HVAE) 3 Variational Diffusion Models(VDM)4 三个等价的解释4.1 预测图片4.2 预测噪声4.3 预测分数 5 Guidance5.1 Class…

【项目设计】从零实现一个高并发内存池

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《项目设计》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;项目介绍&…

005-Spring 扩展点 :PostProcess

目录 Spring 扩展点 &#xff1a;PostProcess介绍PostProcess大纲文字明细使用方法示例Autowired 功能实现Resource 功能实现 后记 Spring 扩展点 &#xff1a;PostProcess 介绍 Spring 核心做的事情其实很简单就是&#xff1a;控制反转和依赖注入 也就是把 Class 解析为 Bea…

npm install ffi各种失败,换命令npm i ffi-napi成功

网上各种帖子安装ffi&#xff0c;基本上到了windows build tools这里会卡住。 使用命令npm install --global --production windows-build-tools 安装报错信息如下&#xff1a; PS E:\codes\nodejsPath\tcpTest> npm install --global --production windows-build-tools …

06-加密算法

加密算法 一、前言知识1、加密解密2、MD5&#xff08;最常见&#xff09;3、SHA4、进制5、时间戳6、URL编码7、base64编码8、unescape编码9、AES加密10、DES&#xff08;类似于base64&#xff09; 二、常见加密形式算法解析三、演示案例1、某 CTF 比赛题目解析2、某 CMS 密码加…

【不带权重的TOPSIS模型详解】——数学建模

目录索引 定义&#xff1a;问题引入&#xff1a;不合理之处&#xff1a;进行修改&#xff1a; 指标分类&#xff1a;指标正向化&#xff1a;极小型指标正向化公式&#xff1a;中间型指标正向化公式&#xff1a;区间型指标正向化公式&#xff1a; 标准化处理(消去单位)&#xff…

pytorch报错torch.cuda.is_available()结果false处理方法

文章目录 问题及起因问题起因 解决方法 问题及起因 问题 前几天跑项目&#xff0c;笔记本上的GPU可以正常跑起来。要跑VAE模型&#xff0c;重新安装了torch,GPU就无法使用了&#xff0c;我重新安装了 cuda,torch.cuda.is_available()的结果依然是False。 起因 配置项目环境…

测试人员的BUG防不胜防

“灵异事件&#xff01;程序里发现了新Bug但是它正常运行啦&#xff01;”、“谁敢信&#xff0c;我电脑死机竟然是因为放青藏高原的时候硬盘共振振幅太大了——”…… 人生处处有Bug&#xff0c;哪一个最令你目瞪口呆&#xff0c;久久不能忘怀&#xff1f;今天就来浅浅分享一…

Spring系列篇--关于IOC【控制反转】的详解

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.什么是Spring 二.Spring的特点 三.什…

TCP服务器—实现数据通信

目录 前言 1.接口介绍 2.编写服务器 3.编写客户端 4.编译链接 5.测试 6.总结 前言 今天我们要介绍的是使用TCP协议实现数据通信&#xff0c;相比于之前写的UDP服务器实现数据信&#xff0c;在主体逻辑上并没有差别。客户端向服务器发送信息&#xff0c;服务器接受信息并回…

如何进行无线网络渗透测试?

今天我们将继续深入探讨Kali Linux的应用&#xff0c;这次我们将重点介绍如何使用Kali Linux进行无线网络渗透测试。无线网络渗透测试是评估无线网络安全性的重要步骤&#xff0c;而Kali Linux作为一款专业的渗透测试发行版&#xff0c;提供了丰富的工具来帮助你进行这项任务。…

支持https访问

文章目录 1. 打开自己的云服务器的 80 和 443 端口2. 安装 nginx3. 安装 snapd4. 安装 certbot5. 生成证书6. 拷贝生成的证书到项目工作目录7. 修改 main.go 程序如下8. 编译程序9. 启动程序10. 使用 https 和端口 8081 访问页面成功11. 下面修改程序&#xff0c;支持 https 和…

【RocketMQ】NameServer总结

NameServer是一个注册中心&#xff0c;提供服务注册和服务发现的功能。NameServer可以集群部署&#xff0c;集群中每个节点都是对等的关系&#xff08;没有像ZooKeeper那样在集群中选举出一个Master节点&#xff09;&#xff0c;节点之间互不通信。 服务注册 Broker启动的时候会…

grafana-zabbix基础操作篇------导入数据源

文章目录 一、grafana的安装1.1、下载地址1.2、下载后导入所安装机器1.3、yum安装解决依赖1.4、启动grafana1.5、查看端口是否启用&#xff08;端口默认3000&#xff09;1.6、浏览器访问 二、添加zabbix数据源2.1、导入数据源 **下一篇 我们讲讲构建仪表板的操作** 今天&#x…

SpringMVC拦截器的介绍,拦截器的基本实现,拦截器链配置

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 拦截器 一、拦截器概念二、拦截器与过滤器的区别三、拦截器…

【ChatGLM】ChatGLM-6B模型Win+4GB显卡本地部署笔记

ChatGLM-6B是清华大学知识工程和数据挖掘小组发布的一个类似ChatGPT的开源对话机器人&#xff0c;由于该模型是经过约1T标识符的中英文训练&#xff0c;且大部分都是中文&#xff0c;因此十分适合国内使用。 预期环境 本机电脑备注&#xff1a; Win10专业版 32G内存256固态系统…

【BASH】回顾与知识点梳理(三十一)

【BASH】回顾与知识点梳理 三十一 三十一. 进程的管理31.1 给进程发送讯号kill -signal PIDlinux系统后台常驻进程killall -signal 指令名称 31.2 关于进程的执行顺序Priority 与 Nice 值nice &#xff1a;新执行的指令即给予新的 nice 值renice &#xff1a;已存在进程的 nice…