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

Spring为什么要用三级缓存解决循环依赖?

Spring为什么要用三级缓存解决循环依赖?

    • 1. Spring是如何创建一个bean对象
    • 2. Spring三级缓存
      • 2.1 一级缓存:单例池,经历过完整bean生命,单例Bean对象
      • 2.2 二级缓存:提前暴露的Bean
      • 2.3 三级缓存:打破循环
    • 3. Spring 解决不了的循环依赖
    • 4.总结

1. Spring是如何创建一个bean对象

  1. 推断构造方法
    默认采用无参构造,如果不存在无参构造,判断有参构造受否唯一,如果唯一选择有参构造,不唯一报错。

  2. 普通对象

  3. 依赖注入

  4. 初始化前(@PostConstruct)
    在类中方法上添加@PostConstruct注解,该方法会在初始化前执行。

  5. 初始化(InitializingBean)
    类实现InitializingBean接口,重写afterPropertiesSet方法。

  6. 初始化后(AOP)

  7. 代理对象

  8. 放入Map单例池

  9. Bean对象

2. Spring三级缓存

在这里插入图片描述

通过分析源码:
doCreateBean方法

2.1 一级缓存:单例池,经历过完整bean生命,单例Bean对象

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

2.2 二级缓存:提前暴露的Bean

private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

2.3 三级缓存:打破循环

private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

//<beanName, 单例创建的工厂>

在创建bean 的源码中先判断是否是单例,支持循环依赖,当前正在创建的单例, 满足上面条件就会创建一个lambda表达式放入三级缓存中。
getEarlyBeanReference方法中会判断是否存在AOP,存在就创建代理对象,不存在就返回通过构造方法创建的普通对象。

在这里插入图片描述
在三级缓存lambda方法中判断是否创建代理对象
在这里插入图片描述

上边源码中看到只要走三级缓存的会调用getEarlyBeanReference方法,该方法会把执行过AOP的Bean存放在earlyProxyReferences的Map集合中,用于后续bean生命周期的初始化后是否AOP创建代理对象校验。

在这里插入图片描述

初始化后,校验是否AOP创建代理对象,通过校验earlyProxyReferences集合中bean是否与传入bean相同来判断。

在这里插入图片描述

获取单例bean
在这里插入图片描述

3. Spring 解决不了的循环依赖

1.构造器循环依赖(实例化阶段循环依赖) 解决办法添加@Lazy注解
底层原理是创建代理对象,
在这里插入图片描述

4.总结

在Java Spring的厨房里,循环依赖这道菜可是让不少程序员大厨头疼的“黑暗料理”。但Spring大厨微微一笑,不慌不忙地亮出了他的秘密武器——三级缓存“时光机”!
一级缓存,那是“秒出”区,新鲜出炉的Bean直接上桌,快得就像外卖小哥的闪电送。
二级缓存,咱们叫它“半成品天堂”,Bean们在这里稍作休息,等待最后的调味。但别急,好戏还在后头!
重头戏来了,三级缓存——“未来豆预测局”!这里,Spring大厨仿佛拥有了预知未来的超能力,提前把即将诞生的Bean们“画”在纸上,等它们真正诞生时,直接对号入座,无缝衔接。这操作,简直比科幻电影还炫酷!
就这样,Spring大厨用三级缓存的“时光机”,轻松玩转循环依赖这道难题,让厨房里的Bean们手拉手也能和谐共处,共同烹饪出美味的应用大餐。程序员们纷纷点赞:“Spring大厨,你是我们的超级英雄!”

在这里插入图片描述

相关文章:

Spring为什么要用三级缓存解决循环依赖?

Spring为什么要用三级缓存解决循环依赖&#xff1f; 1. Spring是如何创建一个bean对象2. Spring三级缓存2.1 一级缓存&#xff1a;单例池&#xff0c;经历过完整bean生命&#xff0c;单例Bean对象2.2 二级缓存&#xff1a;提前暴露的Bean2.3 三级缓存&#xff1a;打破循环 3. S…...

【Redis入门到精通三】Redis核心数据类型(List,Set)详解

目录 Redis数据类型 ​编辑 1.List类型 &#xff08;1&#xff09;常见命令 &#xff08;2&#xff09;内部编码 2.Set类型 &#xff08;1&#xff09;常见命令 &#xff08;2&#xff09;内部编码 Redis数据类型 查阅Redis官方文档可知&#xff0c;Redis提供给用户的核…...

本科生如何学习机器学习

一、入门阶段 1. 数学与统计学基础 高等数学&#xff1a;学习微积分、极限、级数等基本概念。线性代数&#xff1a;掌握矩阵运算、特征值和特征向量、线性方程组等。概率论与统计学&#xff1a;理解概率分布、假设检验、贝叶斯定理等统计知识。 2. 编程语言学习 Python&…...

海康威视摄像机和录像机的监控与回放

文章目录 海康威视摄像机和录像机的监控与回放1、海康威视监控设备简介1.1、摄像机二次开发1.1.1&#xff1a;协议选择 1.2&#xff1a;web集成1.2&#xff1a;标准协议对接1.2.1&#xff1a;ffmpeg软件转流1.2.2&#xff1a;开源监控软件shinobi1.2.2.1 安装使用1.2.2.2 shino…...

校医务室健康服务系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;医生管理&#xff0c;医患交流管理&#xff0c;预约医生管理&#xff0c;健康打卡管理&#xff0c;运动打卡管理&#xff0c;饮食打卡管理 微信端账号功能包括&#xff1a;系统首…...

MySQL 中的 UTF-8 与 UTF8MB4:差异解析

在 MySQL 数据库中&#xff0c;字符集的选择对于数据的存储和处理至关重要。其中&#xff0c;UTF-8 和 UTF8MB4 是两个常见的字符集选项。那么&#xff0c;它们之间到底有什么区别呢&#xff1f; 一、字符集简介 UTF-8 UTF-8&#xff08;8-bit Unicode Transformation Format&…...

nvm无法下载npm的问题

1、问题 执行 nvm install 14.21.3 命令&#xff0c;node可以正常下载成功&#xff0c;npm下载失败 2、nvm配置信息 …/nvm/settings.txt root: D:\soft\nvm path: D:\soft\nodejs node_mirror: npmmirror.com/mirrors/node/ npm_mirror: registry.npmmirror.com/mirrors/…...

数据结构与算法——Java实现 6.递归

要学会试着安静下来 —— 24.9.17 一、递归的定义 计算机科学中&#xff0c;递归是一种解决计算问题的方法&#xff0c;其中解决方案取决于同一类问题的更小子集 说明: ① 自己调用自己&#xff0c;如果说每个函数对应着一种解决方案&#xff0c;自己调用自己意味着解决方案是…...

.Net Core 生成管理员权限的应用程序

创建一个ASP.NET Core Web API项目 给解决方案设置一个名称 选择一个目标框架&#xff0c;这里选择的是 .NET 8.0框架 在Porperties文件夹中添加一个app.manifest文件 设置app.manifest文件属性&#xff0c;生成操作设置为嵌入的资源 双击解决方案名称&#xff0c;编辑WebAppli…...

DAY15:链表实现学生信息管理系统

要求功能&#xff1a; 创建学生信息表 头插法输入学生信息 尾插法输入学生信息输出任意位置范围内的学生信息 头删法删除学生信息尾删法删除学生信息按位置添加学生信息按位置删除学生信息 按位置修改学生信息按位置查找学生信息释放空间 今天有点累&#xff0c;懒得写注释了&a…...

JAVA语法基础 day05-面向对象

一、面向对象基本概念 /* 面向对象编程的步骤&#xff1a; 1.先设计对象的模板&#xff0c;也就是一个类class 生成一个新类的语句是&#xff1a;public class 类名,就跟python中class 类名一样 2.通过new关键字生成具体的对象&#xff0c;每new一次代表创建了的一个新的对象*…...

关于RabbitMQ重复消费的解决方案

一、产生原因 RabbitMQ在多种情况下可能会出现消息的重复消费。这些情况主要包括以下几个方面&#xff1a; 1. 网络问题 网络波动或中断&#xff1a;在消息处理过程中&#xff0c;由于网络波动或中断&#xff0c;消费者向RabbitMQ返回的确认消息&#xff08;ack&#xff09;…...

【SSM-Day2】第一个SpringBoot项目

运行本篇中的代码&#xff1a;idea专业版或者idea社区版本&#xff08;2021.1~2022.1.4&#xff09;->这个版本主要是匹配插件spring boot Helper的免费版(衰) 【SSM-Day2】第一个SpringBoot项目 框架->Spring家族框架快速上手Spring BootSpring Boot的作用通过idea创建S…...

【PyTorch】张量操作与线性回归

张量的操作 Tensor Operation 拼接与切分 1.1 torch.cat() torch.cat(tensors, dim0, outNone)功能&#xff1a;将张量按维度dim进行拼接 tensors&#xff1a;张量序列dim&#xff1a;要拼接的维度 1.2 torch.stacok() torch.stack(tensors, dim0, outNone)功能&#xf…...

情感类智能体——你的微信女神

智能体名称&#xff1a;你的微信女神 链接&#xff1a;文心智能体平台AgentBuilder | 想象即现实 (baidu.com)https://agents.baidu.com/agent/preview/RulbsUjIGj4wsinydlBH7AR3NQKFungt 简介 “你的微信女神”是一个直率的智能体&#xff0c;她用犀利而真实的言辞帮助用户…...

基于SpringBoot+Vue+MySQL的养老院管理系统

系统展示 管理员界面 家属界面 系统背景 随着全球人口老龄化的加速&#xff0c;养老院管理面临着前所未有的挑战。传统管理方式存在信息不透明、效率低下、资源分配不均等问题&#xff0c;难以满足日益增长的养老服务需求。因此&#xff0c;开发一套智能化、高效的养老院管理系…...

大数据Flink(一百二十二):阿里云Flink MySQL连接器介绍

文章目录 阿里云Flink MySQL连接器介绍 一、特色功能 二、​​​​​​​语法结构 三、​​​​​​​​​​​​​​WITH参数 阿里云Flink MySQL连接器介绍 阿里云提供了MySQL连接器&#xff0c;其作为源表时&#xff0c;扮演的就是flink cdc的角色。 一、特色功能 MySQ…...

FutureTask源码分析

Thread类的run方法返回值类型是void&#xff0c;因此我们无法直接通过Thread类获取线程执行结果。如果要获取线程执行结果就需要使用FutureTask。用法如下&#xff1a; class CallableImpl implements Callable{Overridepublic Object call() throws Exception {//do somethin…...

Highcharts甘特图基本用法(highcharts-gantt.js)

参考官方文档&#xff1a; https://www.highcharts.com/docs/gantt/getting-started-gantt https://www.highcharts.com/demo/gantt/project-management https://www.hcharts.cn/demo/gantt 链接在下面按需引入 https://code.highcharts.com/gantt/highcharts-gantt.js htt…...

【Linux庖丁解牛】—Linux基本指令(上)!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a; Linux庖丁解牛 &#x1f516;克心守己&#xff0c;律己则安 目录 1、 pwd命令 2、ls 指令 3、cd 指令 4、Linux下的根目录 5、touch指令 6、 stat指令 7、mkdi…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...