Spring源码深度解析:三级缓存机制探究

在Spring框架中,三级缓存机制是容器初始化Bean过程中的一个重要组成部分。它有效地解决了循环依赖的问题,特别是在单例Bean的初始化过程中。本文将深入探讨Spring的三级缓存机制,并通过代码片段来解析其工作原理。

一、三级缓存概述

Spring的三级缓存是为了解决循环依赖问题而设计的。在Spring的IoC容器中,Bean的创建和初始化过程分为多个阶段,其中涉及到了多个缓存。这三个缓存分别是:

  1. 一级缓存(singletonCache):用于存储完全初始化好的单例Bean实例。

  2. 二级缓存(earlySingletonCache):用于存储已经创建好实例但还未进行属性填充和初始化方法调用的单例Bean。

  3. 三级缓存(singletonFactories):存储的是ObjectFactory对象,这些对象能够生成对应Bean的早期引用。

二、三级缓存机制的工作流程

  • 创建Bean实例:当Spring IoC容器需要创建一个Bean时,首先会调用Bean的构造函数来创建实例。此时,这个Bean的实例会被包装成一个ObjectFactory对象,并放入三级缓存中。

  • 属性填充:接着,Spring会尝试为Bean填充属性。如果属性是另一个Bean的引用,那么Spring会尝试去获取这个引用的Bean。如果这个Bean已经存在于一级缓存中,那么直接获取;否则,会检查二级缓存和三级缓存。

  • 处理循环依赖:如果在填充属性时发现依赖的Bean在三级缓存中存在,那么Spring会调用这个ObjectFactory对象来获取Bean的早期引用。然后,将这个早期引用放入二级缓存中,并继续填充属性。这样,即使存在循环依赖,Spring也能够通过早期引用来解决。

  • 初始化Bean:当所有的属性都被填充完毕后,Spring会调用Bean的初始化方法(如果有的话)。此时,Bean的状态从早期引用变成了完全初始化好的实例,并被放入一级缓存中。

  • 完成初始化:最后,Spring会从二级缓存中移除这个Bean的早期引用,并从三级缓存中移除对应的ObjectFactory对象。

三、代码片段解析

以下是一个简化的Spring源码片段,用于说明三级缓存的核心逻辑:

// 假设这是Spring IoC容器的部分实现  public class DefaultSingletonBeanRegistry {  // 一级缓存  private final Map<String, Object> singletonCache = new ConcurrentHashMap<>(256);  // 二级缓存  private final Map<String, Object> earlySingletonCache = new HashMap<>(16);  // 三级缓存  private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);  // ... 其他方法 ...  protected Object getSingleton(String beanName, boolean allowEarlyReference) {  // 首先尝试从一级缓存中获取  Object singletonObject = this.singletonCache.get(beanName);  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {  // 如果一级缓存中没有,且Bean正在创建中,则尝试从二级和三级缓存中获取  synchronized (this.singletonObjects) {  singletonObject = this.earlySingletonCache.get(beanName);  if (singletonObject == null && allowEarlyReference) {  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);  if (singletonFactory != null) {  // 从三级缓存中获取ObjectFactory并创建早期引用  singletonObject = singletonFactory.getObject();  this.earlySingletonCache.put(beanName, singletonObject);  this.singletonFactories.remove(beanName);  // ... 后续可能需要移除二级缓存中的早期引用,并放入一级缓存 ...  }  }  }  }  return singletonObject;  }  // ... 其他方法 ...  }

在上面的代码片段中,getSingleton方法用于从缓存中获取Bean实例。它首先检查一级缓存,然后检查二级缓存和三级缓存。如果Bean在三级缓存中存在,则通过调用ObjectFactory的getObject方法来获取早期引用,并将其放入二级缓存中。

四、总结

Spring的三级缓存机制是解决循环依赖问题的重要手段。通过合理利用这三个缓存,Spring能够在Bean的创建和初始化过程中保持灵活性,同时确保Bean的依赖关系能够正确解析。理解这一机制有助于我们更深入地掌握Spring IoC容器的实现原理,并在实际开发中更好地利用Spring框架的特性。

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

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

相关文章

查看HDF5文件软件(HDFView)

HDFView&#xff1a;下载地址 note&#xff1a;我们需要下载 win10 、App软件&#xff08;win10在win11也能运行&#xff09;&#xff0c;因为App软件是轻量版&#xff0c;不需要安装就可以使用。 eg&#xff1a; 下载完后解压就可以使用。

MATLAB 2016计算NDVI

MATLAB 2016计算NDVI 之前大二的一段MATLAB代码&#xff0c;突然找到&#xff0c;记录一下当时初学MATLAB的程序&#xff0c;用于读取TIFF计算归一化植被指数&#xff08;NDVI&#xff09;并将其保存为TIFF文件。 文章目录 MATLAB 2016计算NDVI读取波段数据初始化NDVI矩阵和转…

配置SSL证书需要几步,有免费的吗

我们要明白什么是SSL证书。SSL&#xff08;Secure Sockets Layer&#xff09;是一种安全协议&#xff0c;用于在互联网上进行信息加密传输&#xff0c;保护数据不被第三方窃取或篡改。SSL证书就是用来执行这种加密的一种数字证书&#xff0c;它可以提供身份验证&#xff0c;防止…

这个合租室友真的没有一点公德心,还好他搬走了

这个合租室友真的没有一点公德心&#xff0c;还好他搬走了 这个出租屋有四个房间。 有三个卧室&#xff0c;和一个隔断。 我住三个卧室中的一个。下图中右边那个就是我住的。 2023年下半年&#xff0c;左边那个屋子来了一个新租户小白。 在住的过程中&#xff0c;隔断间的租…

30V-STM32设计项目

30V-STM32设计 一、项目描述 (已验证) 基于STM32c8t6芯片设计的开发板&#xff0c;支持4-30V宽电压输入&#xff0c;串口模式自动下载功能&#xff0c;支持串口和STlink&#xff0c;方式下载程序 二、原理图介绍 电源电路采用了DCDCLDO电路&#xff0c;如果是外接DC头供电的话&…

Spring Boot 3.2.5 集成 mysql

版本 Spring Boot 3.2.5 第一步&#xff0c;添加必要依赖 // mysql jdbc 及 驱动 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency><gr…

什么是graphQL

文章目录 一、入门1.是什么&#xff1f;做什么2.如何做&#xff1f; 二、查询和变更1.字段&#xff08;Fields&#xff09;2.参数&#xff08;Arguments&#xff09;3.别名&#xff08;Aliases&#xff09;4.片段&#xff08;Fragments&#xff09;5.操作名称&#xff08;Opera…

你知道数据是如何为制造业精益生产KPI和供应链管理赋能的吗?

挖掘工业数据价值&#xff0c;形成新质生产力 随着工业4.0的逐步深入和国家对制造业高质量发展的大力扶持&#xff0c;工业数据的重要性愈发凸显&#xff0c;已然成为生产经营活动中不可或缺的核心要素。 工业数据不仅反映了生产流程中的各个环节&#xff0c;更蕴含了丰富的信…

嵌入式单片机的高级编程技巧和优化

引言 嵌入式单片机&#xff08;MCU&#xff09;是实现智能设备控制的核心&#xff0c;广泛应用于工业自动化、智能家居、医疗设备等领域。 下面将探讨STM32单片机的高级编程技巧&#xff0c;包括中断管理、低功耗模式和内存优化等方面&#xff0c;并提供具有一定难度的代码示…

深度学习的炼金术:转化数据为黄金的秘密

深度学习的炼金术&#xff1a;转化数据为黄金的秘密 1 引言 在现代深度学习的壮阔疆域中&#xff0c;数据是王冠上耀眼的宝石&#xff0c;而性能优化则是锻造这顶王冠的炼金术。这份融合了数据和算法魔力的艺术&#xff0c;不仅仅依赖于强大的计算资源和复杂的网络结构&#x…

【蓝桥杯省赛真题40】python摘苹果 中小学青少年组蓝桥杯比赛 算法思维python编程省赛真题解析

目录 python摘苹果 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python摘苹果 第十三届蓝桥杯青少年组python编程省赛真题 一、题目要求 &…

【C语言】万字详讲操作符

目录 前言 一、操作符分类 二、算数操作符 三、移位操作符 四、位操作符 五、赋值操作符 六、单目操作符 6.1 逻辑反操作 6.2 负值与正值 6.3 取地址 6.4 sizeof 6.5 取反操作符 6.6 --和操作符 6.7 间接访问操作符&#xff08;解引用操作符&#xff09; 6.8 强…

QA | amfori QMI 审核常见问题解答

01amfori QMI 项目介绍 作为全球领先的贸易协会&#xff0c;amfori 致力于开放和可持续贸易。他们汇集了来自 40 多个国家的零售商、进口商、品牌和协会&#xff0c;目的是系统地监督和改善世界各地的供应商的工作条件。 amfori QMI 是一项针对致力于为生产现场的作业规范和质量…

level2行情+在线金融数据库

jvQuant&#xff1a;一站式金融量化服务平台 jvQuant作为一个领先的金融量化服务平台&#xff0c;为广大投资者和量化分析师提供了全面、高效、稳定的数据接入和量化分析服务。该平台涵盖了多个关键功能&#xff0c;包括交易接入、WebSocket行情接入、历史行情查询、在线数据库…

安装JAVA和java IDEA并汉化过程

1.安装java: 打开java的下载链接&#xff1a; Java Downloads | Oracle 然后选择对应的版本下载即可&#xff0c;我这里是windows 所以下载这个 然后正常一步步安装即可。 2.配置java环境&#xff1a; 在桌面右键此电脑然后点击属性——高级系统设置——环境变量——然后…

H5点击复制功能 兼容安卓、IOS

效果图 HTML代码 <div>链接&#xff1a;<span style"color: #FF8A21" click"CopyUrl" id"copyId"> https://blog.csdn.net/qq_51463650?spm1000.2115.3001.5343</span> </div>复制方法 const CopyUrl () > {let …

12.Blender 界面介绍(上)及物体基础编辑操作

设置语言 首先在菜单栏打开编辑-Preferences-界面-翻译&#xff0c;可以修改语言 这里使用的是Steam上下载的4.1版本 工具栏 左边的工具栏&#xff0c;按T就会出现&#xff0c;再按T就会隐藏 右边的工具栏是按N&#xff0c;按N显示&#xff0c;再按N隐藏 旋转画面 长按鼠…

微信小程序监听App中的globalData——全局数据监听

微信小程序监听App中的globalData——全局数据监听 定义数据定义监听方法注册监听方法修改监听的数据扩展 需求&#xff1a;微信小程序项目需要全局监听某个数据。 方法&#xff1a;在 app.ts/app.js 中定义 globalData 公共数据&#xff0c;然后定义一个监听方法 watch&…

CSS 标准流 浮动 Flex布局

目录 1. 标准流2. 浮动2.1 清除浮动 3. Flex 布局3.1 Flex 组成3.2 Flex 布局 - 主轴与侧轴对齐方式3.2.1 主轴对齐方式3.2.2 侧轴对齐方式 3.3 Flex 布局 - 修改主轴方向3.4 Flex 布局 - 弹性伸缩比3.5 Flex 布局 - 弹性盒子换行3.6 Flex 布局 - 行对齐方式 1. 标准流 标准流…

使用selenium时出现element click intercepted报错的解决办法

win10&#xff0c;python3.8.10。 selenium版本如下&#xff08;用pip38 show selenium查看&#xff09;&#xff1a; 在定位中&#xff0c;定位了一个按钮&#xff08;特点&#xff1a;button下还有span然后才是文本&#xff09;&#xff0c;代码如下&#xff1a; from sele…