Spring中的循环依赖问题

news2024/11/20 20:37:06

文章目录

  • 前言
  • 一、什么是循环依赖?
  • 二、三级缓存
  • 三、图解
  • 三级缓存总结


前言

本文章将讲解Spring循环依赖的问题


一、什么是循环依赖?

一个或多个对象之间存在直接或间接的依赖关系,这种依赖关系构成一个环形调用,有下面 3 种方式。

![在这里插入图片描述](https://img-blog.csdnimg.cn/3142f6a04b31455f853e4f1403c0ea29.png

模拟一个情况2的Demo

@Service
public class Service {
	@Autowried
	Dao dap;
}
@Repository
class Dao{
	@Autowried
	Service service;
}

在这里插入图片描述

这是一个经典的循环依赖,如果spring没有处理循环依赖,那么在他们需要注入对方属性时,会一直循环等待对方注入属性,导致无限循环。

二、三级缓存

Spring为了解决循环引用的问题,提供了三级缓存的存储方式

public class DefaultSingletonBeanRegistry ... {
//1、最终存储单例Bean成品的容器,即实例化和初始化都完成的Bean,称之为"一级缓存"
Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//2、早期Bean单例池,缓存半成品对象,且当前对象已经被其他对象引用了,称之为"二级缓存"
Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
//3、单例Bean的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建Bean,称之为"三
级缓存"
Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
}
注:将对象保存至三级缓存的时候,会包装成ObjectFactory对象录入,未来通过此接口对应的get方法再
次提取对象

三、图解

在这里插入图片描述

图解描述:

  • A实例化对象,但尚未初始化,将A存储到三级缓存中;
  • A属性注入,发现需要B对象,从缓存中取,发现没有B对象;
    • B实例化对象,但尚未初始化,将B放到三级缓存
    • B属性注入,需要A对象,从三级缓存中通过工厂获取A对象,再将A从三级缓存移除到二级缓存,
    • B执行其他生命周期的过程,最终成为一个完全体Bean,存储到一级缓存,删除二三级缓存
  • A注入B对象
  • A执行其他生命周期过程,最终成为一个完全体Bean,存储到一级缓存,删除二三级缓存

三级缓存总结

  • 一级缓存:为“Spring 的单例属性”而生 ,就是个单例池,用来存放已经初始化完成的单例 Bean;
  • 二级缓存:为“解决 AOP”而生 ,存放的是半成品的 AOP 的单例 Bean;
  • 三级缓存:为“打破循环”而生 ,存放的是生成半成品单例 Bean 的工厂方法

如果没有AOP的话,其实只需要一、三级缓存,就可以解决循环引用的问题;

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

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

相关文章

根据数组中各值是否满足指定条件决定是否将其按指定规则计算更新numpy.putmask()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 根据数组中各值是否满足指定条件 决定是否将其按指定规则计算更新 numpy.putmask() 选择题 以下程序的运行结果是? import numpy as np xnp.array([1,2,3,4,5]) print("【显示】x:\n&quo…

【Spring】如果你需要使用重试机制,请使用Spring官方的Spring Retry

文章目录 前言Spring Retry的基本使用第一步&#xff0c;引入Spring Retry的jar包第二步&#xff0c;构建一个RetryTemplate类第三步&#xff0c;使用RETRY_TEMPLATE注意事项 拓展方法降级操作重试策略&#xff1a;时间策略重试策略&#xff1a;指定异常策略 前言 Spring Retr…

Vue3 第五节 一些组合式API和其他改变

1.provide和inject 2.响应式数据判断 3.Composition API的优势 4.新的组件 5.其他改变 一.provide和inject 作用&#xff1a;实现祖与后代组件间通信 套路&#xff1a;父组件有一个provide选项来提供数据&#xff0c;后代组件有一个inject选项来开始使用这些数据 &…

centos 7镜像(iso)下载图文教程(超详细)

声明&#xff1a;本教程为本人学习笔记&#xff0c;仅供参考 文章目录 前言一、阿里云镜像站下载centos 7 二、清华源下载centos 7小结 前言 声明&#xff1a;本教程为本人学习笔记&#xff0c;仅供参考 本教程将提供两种方式下载centos 7 系统镜像 1、阿里巴巴开源镜像站 2、…

Unity之ShaderGraph 节点介绍 Procedural节点

程序化 噪声Gradient Noise&#xff08;渐变或柏林噪声&#xff09;Simple Noise&#xff08;简单噪声&#xff09;Voronoi&#xff08;Voronoi 噪声&#xff09; 形状Ellipse&#xff08;椭圆形&#xff09;Polygon&#xff08;正多边形&#xff09;Rectangle&#xff08;矩形…

VM虚拟机和主机互相ping不通,但是ssh能连上,也能访问外网

直接还原默认设置&#xff0c;然后点确定 注意&#xff0c;你还原设置以后ip也会变&#xff0c;ifconfig自己重新看一下

大数据-玩转数据-Sink到Kafka

一、添加Kafka Connector依赖 pom.xml 中添加 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-connector-kafka_${scala.binary.version}</artifactId><version>${kafka.version}</version></dependency&g…

IMV4.0

背景内容&#xff1a; 经历了多个版本&#xff0c;基础内容在前面&#xff0c;可以使用之前的基础环境&#xff1a; v1&#xff1a; https://blog.csdn.net/wtt234/article/details/132139454 v2&#xff1a; https://blog.csdn.net/wtt234/article/details/132144907 v3&#…

Docker mysql+nacos单机部署

docker 网络创建 由于nacos需要访问mysql的数据&#xff0c;因此mysql容器和nacos容器之间需要进行通信。容器间通信有很多方式&#xff0c;在这里采用同一网络下的方式进行实现。因此需要创建网络。创建网络的命令如下&#xff1a; docker network create --driver bridge n…

致远OA任意管理员登录

真的&#xff0c;如果痛苦不能改变生存&#xff0c;那还不如平静地将自己毁灭。毁灭。一切都毁灭了&#xff0c;只有生命还在苟延残喘。这样的生命还有什么存在的价值&#xff1f; 漏洞复现 访问漏洞url 构造payload POST /seeyon/thirdpartyController.do HTTP/1.1methoda…

【数据结构与算法】平衡二叉树(AVL树)

平衡二叉树&#xff08;AVL树&#xff09; 给你一个数列{1,2,3,4,5,6}&#xff0c;要求创建二叉排序树&#xff08;BST&#xff09;&#xff0c;并分析问题所在。 BST 存在的问题分析&#xff1a; 左子树全部为空&#xff0c;从形式上看&#xff0c;更像一个单链表。插入速度…

pg实现月累计

获取每月累计数据&#xff1a; ​​​ SELECT a.month, SUM(b.total) AS total FROM ( SELECT month, SUM(sum) AS total FROM ( SELECT to_char(date("Joinin"),YYYY-MM) AS month , COUNT(*) AS sum FROM "APP_HR_Staff_Basic_Info" GROUP BY month ) …

Vue中使用uuid生成唯一ID(脚手架创建自带的)

1.utils 说明&#xff1a;一般封装工具函数。 // 单例模式 import { v4 as uuidv4 } from uuid; // 要生成一个随机的字符串&#xff0c;且每次执行不能发生变化 // 游客身份还要持久存储 function getUUID(){// 先从本地获取uuid&#xff0c;本地存储里面是否有let uuid_tok…

淘宝整店商品如何批量获取?获取淘宝店铺所有商品接口item_search_shop

在竞争日益激烈的电商行业&#xff0c;不少商家出于以下的考虑&#xff0c;想要实现一键批量获取淘宝店铺的所有商品。 竞争分析&#xff1a;通过获取某个店铺内的所有商品信息&#xff0c;可以对竞争对手的产品进行全面的了解和分析。可以了解到对手的产品种类、价格、销量等情…

git和github学习

一、什么是git和github? 二、学会使用github desktop应用程序 初始使用&#xff1a; 一开始我们是新账户&#xff0c;里面是没有仓库的&#xff0c;需要手动创建一个仓库。此时&#xff0c;这个仓库是创建在本地仓库里面&#xff0c;需要用到push命令&#xff08;就是那个pub…

【C++进阶】:异常

异常 一.异常的概念二.基本使用三.异常重新抛出四.异常规范五.异常安全六.异常的优缺点 一.异常的概念 c语言 传统的错误处理机制&#xff1a; 1. 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。…

PCL 大规模点云显示

文章目录 一、什么是LOD?二、基本思想三、LOD算法常见的实现方式四、PCL库中LOD的实现官方代码结果展示参考文献:随着三维激光扫描技术的发展,我们目前能采集到 海量的点云数据,但是如何将千万甚至上亿级别的点云进行流畅显示,一直以来都是困扰业界的一大难题。尤其在早期…

volte端到端问题分析(一)

1、MME专载保持功能验证 **描述&#xff1a;**当无线环境较差时&#xff0c;有可能由于“Radio_Connection_with_UE_Lost” 原因造成的VoLTE通话掉话&#xff0c;如果UE发生RRC重建成功&#xff0c;手机将不会掉话。 对MME1202进行功能验证&#xff1a;开启后&#xff0c;MME专…

react-virtualized可视化区域渲染的使用

介绍 github地址&#xff1a;https://github.com/bvaughn/react-virtualized 实例网址&#xff1a;react-virtualized如果体积太大&#xff0c;可以参考用react-window。 使用 安装&#xff1a; yarn add react-virtualized。在项目入口文件index.js中导入样式文件&#xff…

Linux下QtCreator勾选Use root user后出现error while loading shared libraries的问题

文章目录 背景解决办法其他解决办法 背景 在linux下调试程序时&#xff0c;有时候需要取得root权限才能连接操作某些设备。 之前我是通过脚本方式 [在QtCreator中先执行自定义命令再执行程序]来进行的。也就是在脚本中取得权限&#xff0c;脚本内容类似这样&#xff1a; echo…