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

Spring 是如何解决循环依赖问题的?

项目场景:

提示:这里简述项目相关背景:

例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大)


问题描述

        我们都知道,如果在代码中,将两个或多个 Bean 互相之间持有对方的引用就会发生循环依赖。循环的依赖将会导致注入死循环,这是 Spring 发生循环依赖的原因。

        循环依赖有三种形态:

                第一种,互相依赖:A 依赖 B,B 又依赖 A,它们之间形成了循环依赖。

                 第二种,三者间依赖:A 依赖 B,B 依赖 C,C 又依赖 A,形成了循环依赖。

 

                第三种,自我依赖:A 依赖 A 形成了循环依赖。

                   


问题解决:

        Spring 中设计了三级缓存来解决循环依赖问题,当我们去调用 getBean()方法的时候,Spring 会先从一级缓存中去找到目标 Bean,如果发现一级缓存中没有便会去二级缓存中去找,而如果一、二级缓存中都没有找到,意味着该目标 Bean 还没有实例化

        于是,Spring 容器会实例化目标 Bean(PS:刚初始化的 Bean 称为早期 Bean) 。然 后,将目标 Bean 放入到二级缓存中,同时,加上标记是否存在循环依赖。如果不存在循环依赖,便会将目标 Bean 存入到二级缓存,否则,便会标记该 Bean 存在循环依赖, 然后将等待下一次轮询赋值,也就是解析@Autowired 注解。等@Autowired 注解赋值完成后(PS:完成赋值的 Bean 称为成熟 Bean) ,会将目标 Bean 存入到一级缓存。

        这里可以做个总结,我们来看这张图。Spring 一级缓存中存放所有的成熟 Bean, 二级缓存中存放所有的早期 Bean,先取一级缓存,再去二级缓存。 

 


问题扩展

        那么,前面有提到三级缓存,三级缓存的作用是什么?

        回答:三级缓存是用来存储代理 Bean,当调用 getBean()方法时,发现目标 Bean 需要通过代理工厂来创建,此时会将创建好的实例保存到三级缓存,最终也会将赋值好的 Bean 同步到一级缓存中。

        Spring 中哪些情况下,不能解决循环依赖问题?

         1、多例 Bean 通过 setter 注入的情况,不能解决循环依赖问题

         2、构造器注入的 Bean 的情况,不能解决循环依赖问题

         3、单例的代理 Bean 通过 Setter 注入的情况,不能解决循环依赖问题

         4、设置了@DependsOn 的 Bean 的情况,不能解决循环依赖问题

相关文章:

Spring 是如何解决循环依赖问题的?

项目场景: 提示:这里简述项目相关背景: 例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大) 问题描述 我们都知道,如果在代码中,将两个…...

Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发

今日目标 掌握纯注解开发依赖注入(DI)模式 学习使用纯注解进行第三方Bean注入 1 注解开发依赖注入(DI)【重点】 问题导入 思考:如何使用注解方式将Bean对象注入到类中 1.1 使用Autowired注解开启自动装配模式(按类型) Service public class StudentS…...

java 强密码验证策略工具类

java 强密码验证策略工具类 package com.neusoft.caeid.common.utils;import java.util.regex.Matcher; import java.util.regex.Pattern;/*** author dume*/ public class PasswordUtil {public static final String REGEX "^\\S*(?\\S{6,})(?\\S*\\d)(?\\S*[a-zA-Z…...

CI/CD—K8S 基本理解与部署

1 K8S 是什么 Kubernetes 是一款容器的编排调度工具,来源于 Google 开源的 Brog 系统。Kubernetes简称K8S,是用8代替8个字符 “ubernete” 而成的缩写,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化…...

2023网络安全常用工具汇总(附学习资料+工具安装包)

几十年来,攻击方、白帽和安全从业者的工具不断演进,成为网络安全长河中最具技术特色的灯塔,并在一定程度上左右着网络安全产业发展和演进的方向,成为不可或缺的关键要素之一。 话不多说,网络安全10款常用工具如下 1、…...

OpenStack监控工具

OpenStack是一个开源的云计算管理平台项目,是一系列软件开源项目的组合。由NASA和Rackspace合作研发并发起,以Apache许可证(Apache软件基金会发布的一个自由软件许可证)授权。 OpenStack为私有云和公有云提供可扩展的弹性的云计算…...

讲解密码学综合应用

密码学综合应用是指将密码学的理论和技术应用于各种场景中,以保障信息的安全性、完整性和可靠性。密码学的应用范围非常广泛,包括通信安全、网络安全、电子商务、数字签名、认证、密钥管理等。下面将简要介绍一些密码学综合应用的实例: 1. 加…...

Flamingo

基于已有的图像模型和文本模型构建多模态模型。输入是图像、视频和文本,输出是文本。 Vision encoder来自预训练的NormalizerFree ResNet (NFNet),之后经过图文对比损失学习。图片经过图像模型的输出是2D grid,视频按1FPS的频率采样后经过图…...

Leetcode-每日一题【剑指 Offer 12. 矩阵中的路径】

题目 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。 例如,在下面的 34 的矩阵中包含单词 "ABCCED"(单词中的字母…...

安全渗透知识总结二

目录 一、html实体编码 1、Unicode字符编码 2、字符的数字表示 3、常见实体编码 4、url 协议 主机 http状态码 http常用的状态码 端口 常见协议端口 查询参数 锚点 url字符 urlcode字符 绝对url和相对url 二、字符编码 Ascll字符集 html字符集 html的url编码 …...

【线程】wait()+notifyAll()实现多个线程交替遍历,输出ABCABC

背景 有三个线程,每个线程分别循环输出A、B、C,各线程循环10次,要求输出结果是ABCABCABC这样的 代码 Data public class PrintThread extends Thread {private String string; // 输出的字符串private int order; …...

MyBatis 缓存机制复习及项目中的应用经历

背景 想起前两年工作中因为二级缓存默认开启导致的问题,完整的看了一个介绍 MyBatis 缓存机制的视频《MyBatis 缓存基础知识讲解》。 总计知识点: 缓存的类型及开关这是个形同虚设的功能,线上环境应该禁用缓存 MyBatis 缓存分类 MyBasit…...

匈牙利算法详解

匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm),用于求解指派问题(assignment problem),算法时间复杂度为O(N^3)。Harold Kuhn发表于1955年,由于该算法基于两位匈牙利数学家的早期研究成果&#…...

script的三种加载模式

默认加载:阻断dom树构建(html文档解析),下载资源,然后立即执行,完毕后再进行dom树构建defer 加载:下载照旧,但执行延后。即下载资源和dom构建同时进行,但等dom树构建完再执行async:下…...

mongo 中两张表联合查询

表1:user 表 表2:dept表 需要查询user表中roleCodes 包含shr 的数据 然后联合dept表 需要部门名称 db.user.aggregate([{$match: {roleCodes: "shr" // 匹配roleCodes包含"shr"的文档}},{$lookup: {from: "dept", // 关联的集合名称loc…...

【Linux】多路转接 -- epoll

文章目录 1. 认识epoll2. epoll相关系统调用接口3. epoll工作原理4. epoll服务器5. epoll的优点6. epoll的工作方式7. epoll的使用场景 1. 认识epoll epoll系统调用和select以及poll是一样的,都是可以让我们的程序同时监视多个文件描述符上的事件是否就绪。 epoll…...

学会RabbitMQ的延迟队列,提高消息处理效率

系列文章目录 手把手教你,本地RabbitMQ服务搭建(windows) 消息队列选型——为什么选择RabbitMQ RabbitMQ灵活运用,怎么理解五种消息模型 RabbitMQ 能保证消息可靠性吗 推或拉? RabbitMQ 消费模式该如何选择 死信是什么…...

ChatGPT会取代搜索引擎吗?BingChat、GoogleBard与ChatGPT区别

目前暂时不会,ChatGPT为代表的聊天机器人很可能会直接集成到搜索中,而不是取代它。微软已经通过Bing Chat和Bing做到了这一点,它将“聊天”选项卡直接放入Bing搜索的菜单中。Google、百度也分别开始尝试通过其AI生成技术将Google Bard、文心一…...

多个QLabel中文字左右对其问题研究

众所周知,关于QLabel 中的文字对其方式,官方提供多种,具体可参考 AlignmentFlag,这里就不详细列举了。 实际开发中有这样一个需求:多个lab中,文字显示不同,长度不一,但想要实现视觉…...

链式二叉树统计结点个数的方法和bug

方法一: 分治:分而治之 int BTreeSize1(BTNode* root) {if (root NULL) return 0;else return BTreeSize(root->left)BTreeSize(root->right)1; } 方法二: 遍历计数:设置一个计数器,对二叉树正常访问&#…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

【Oracle】分区表

个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

LangFlow技术架构分析

🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

go 里面的指针

指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...