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

【Spring】三级缓存

目录标题

  • 触发所有未加载的实例a - 开始
  • getBean( doGetBean) - 获取单例bean
    • getSingleton() - 获取单例bean
    • createBean(doCreateBean) - 创建bean
      • createBeanInstance - 创建并返回bean
      • addSingletonFactory -放三级缓存
      • populateBean - 属性设值
        • applyPropertyValues - 设值属性
          • 初始化b开始
            • 从缓存中获取b
            • 创建bean-b实例
            • 提前暴露bean-b
            • b 属性设值
            • 放入一级缓存里面
          • 初始化b结束
          • image.png
      • addSingleton- 放一级缓存
  • 触发所有未加载的实例a - 结束
  • 触发所有未加载的实例b - 开始
  • 触发所有未加载的实例b - 结束

结合文章:循环依赖

测试代码如下:

public class A {private B b;public B getB() {return b;}public void setB(B b) {this.b = b;}public A() {System.out.println("---A created success");}
}
public class B {private A a;public A getA() {return a;}public void setA(A a) {this.a = a;}public B() {System.out.println("---B created success");}
}
public class ClientSpringContainer {public static void main(String[] args) {sampleDemo();}private static void sampleDemo() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");A a = context.getBean("a", A.class);B b = context.getBean("b", B.class);}
}

执行refresh 方法
image.png
执行finishBeanFactoryInitialization 方法
image.png
执行preInstantiateSingletons 方法
image.png

触发所有未加载的实例a - 开始

image.png

getBean( doGetBean) - 获取单例bean

实际上就是通过 doGetBean ,先进行 bean-a 的初始化

getSingleton() - 获取单例bean

去缓存查看时候有 bean - a
image.png
实际上就是通过双重校验锁,去查看一级缓存中是否有 bean-a 并且没有在创建中 ,所以就返回 null
image.png
由于返回了 null ,则 继续往下走,去创建bean-a实例
image.png由于我们 bean-a 是单例的,所以就执行下面的语句块
image.png
再进入内部,发现返回的其实就是执行的就是传参的 createBean(beanName, mbd, args)
image.png
image.png

createBean(doCreateBean) - 创建bean

image.png

createBeanInstance - 创建并返回bean

先执行的是 createBeanInstance,里面是通过构造函数去创建一个bean实例
image.png

addSingletonFactory -放三级缓存

继续,需要暴露出这个bean-a到 三级缓存中,此时我们是有了bean-a的实例:A@2321
image.png

  1. 往三级缓存中放入 a - lamdba@2337
  2. 删除二级缓存

image.png

populateBean - 属性设值

image.png

  1. 先解析看看bean -a 需要那些属性
  2. 在进行设值

image.png

applyPropertyValues - 设值属性

image.png
resolveValueIfNecessary 实际上调用了 resolveReference
image.png
resolveReference 也是通过beanFactory 中获取bean
image.png


初始化b开始

而由于此时工厂里面没有bean-b,没有进行初始化
实际上是调用了doGetBean,又开始了 实例化 bean-b的过程,getBean
image.png

从缓存中获取b

查看一级缓存中是否存在bean-b,返回null
image.png

创建bean-b实例

相当于重复了createBean
由于我们在前一步返回的是null,所以就去执行else语句块的内容
image.png
image.png
常见的是单例bean,进入方法,执行的是createBean方法
image.png
image.png
image.png
调用了doCreateBean方法
image.png
createBeanInstance , B@2627
image.png

提前暴露bean-b

addSingletonFactory
image.png
三级缓存中放入 b - lambda@2644
image.png
此处我们也可以看到在三级缓存中有两个
image.png

b 属性设值

调用 populateBean
image.png
applyPropertyValues
image.png
这里我们可以看到 b 是需要a的(符合我们 前面的需求:a b 互相引用)
image.png
applyPropertyValues 里面又调用了 resolveValueIfNecessary
image.png
resolveValueIfNecessary 又调用了 resolveReference
image.png
resolveReference 调用了 beanFactory.getBean,getBean又是通过doGetBean去获取
image.png
image.png
image.png
先从一级缓存中去获取bean-a ,返回null
image.png
由于一级缓存中没有且a在创建中,执行if语句块
image.png
查看二级缓存中是否有a,没有,执行if 语句块
image.png
再从三级缓存中去获取a, 这里是能够获取从三级缓存中获取到的点击访问
image.png
image.png

  1. a ,三级缓存中的实例 lambda@2337 对应的 实例 A@2321
  2. 放入二级缓存中去 A@2321,此时就已经把a放入二级缓存里面了
  3. 删除三级缓存的内容
  4. 返回缓存中的实例 A@2321

image.png
由于能够从三级缓存中去获取到半成品a,A@2321
image.png
doGetBean 返回 从三级缓存中获取到的A@2321,所以执行if语句快,发现最后返回的是bean,bean是通过getObjectForBeanInstance 去获取的
image.png
getObjectForBeanInstance,又去调用了 super.getObjectForBeanInstance
image.png
getObjectForBeanInstance 就是返回了 A@2321
image.png
doGetBean 结束了,返回了b需要的属性 a(虽然是半成品 A@2321)
image.png
resolveReference 结束,返回 A@2321
image.png
resolveValueIfNecessary结束,返回 A@2321
image.png
退回到applyPropertyValues
image.png
完成属性b设值a( A@2321)
image.png
此时populateBean
(回顾:此时就完成了b的setter注入a),完成了b初始化
image.png
继续,由于在前面,bean-b进行了提前暴露,执行if语句块,所以我们这次flase(意味不需要提前暴露了)
image.png
执行getSingleton, 由于从一级缓存中获取不到,且b在创建中,执行if语句块
image.png
从二级缓存中获取bean-b(肯定是没有的),下图中可以看到我们在二级缓存中也获取不到bean-b,并且不需要提前暴露了,所以不需要执行if语句块
image.png
所以就直接返回null
image.png
返回B@2627
image.png
此时我们就结束了对createBean ,并返回B@2627
image.png
于是我们就能够从三级缓存中去获取到b了
返回b 的 getSingleton,此时就是 B@2627
image.png

放入一级缓存里面

而且,此时我们这个是新创建的bean ,因此 newSingleton = true,执行addSingleton
image.png

  1. 放入一级缓存 b - B@2627
  2. 移除三级缓存
  3. 移除二级缓存

image.png
getSingleton 结束,获取到了 b实例 B@2627
image.png
doGetBean 结束,返回 b实例 B@2627,也就是这一步结束了完成b的初始化
image.png

初始化b结束

那么,接下来,继续完成a的初始化。
resolveReference 结束,返回 b实例 B@2627
image.png
resolveValueIfNecessary结束,返回 b实例 B@2627
image.png
设值a的属性b
image.png
populateBean 结束,完成属性赋值
image.png


初始化a ,A@2321
image.png
前面我们说过我们已经提前暴露了a到三级缓存池里面放到三级缓存池
image.png
执行 getSingleton ,由于
一级缓存里面没有a,且a在创建中,所以 执行if语句块
image.png
由于我们在二级缓存里面能够找到a,if语句就不执行了,因为已经完成了对a的放入二级缓存池

image.png

返回二级缓存池中的对象,A@2321
image.png
于是我们就有了早期暴露对象exposedObject,A@2321,doCreateBean结束
image.png
createBean 结束
image.png
doGetBean结束,返回到getSingleton
image.png
由于这是一个新创建的bean,newSingleton = true,执行addSingleton
image.png

addSingleton- 放一级缓存

  1. a 放入一级缓存:a - A@2321
  2. 移除二级缓存
  3. 移除三级缓存

image.png
getSingleton 结束
image.png
doGetBean 结束
image.png

触发所有未加载的实例a - 结束

image.png

触发所有未加载的实例b - 开始

image.png
image.png
执行getSingleton
image.png
此时,我们的b已经放入了一级缓存了哦,此处就已经完成了b放入一级缓存池,不执行if语句块,返回B@2627
image.png
而我们getGetBean的返回对象bean,就是getSingleton 返回的对象B@2627
image.png

触发所有未加载的实例b - 结束

image.png


preInstantiateSingletons 后面一个循环的语句块,由于这次我们关注的是“循环依赖”,就不着重分析这块 就直接过了
image.png
finishBeanFactoryInitialization 执行结束
image.png
refresh 执行结束
image.png
ClassPathXmlApplicationContext 执行结束
image.png


断点数量如下:
image.png


流程示例图
在这里插入图片描述

相关文章:

【Spring】三级缓存

目录标题 触发所有未加载的实例a - 开始getBean( doGetBean) - 获取单例beangetSingleton() - 获取单例beancreateBean(doCreateBean) - 创建beancreateBeanInstance - 创建并返回beanaddSingletonFactory -放三级缓存populateBea…...

CVE-2016-3088(ActiveMQ任意文件写入漏洞)

漏洞描述 1、漏洞编号:CVE-2016-3088 2、影响版本:Apache ActiveMQ 5.x~5.13.0 在 Apache ActiveMQ 5.12.x~5.13.x 版本中,默认关闭了 fileserver 这个应用(不过,可以在conf/jetty.xml 中开启);…...

270.【华为OD机试真题】字符串拼接(深度优先搜索(DFS)-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-字符串拼接二.解题思路三.题解代码Python题解代…...

线阵相机参数介绍之轴编码器控制

1.1 功能介绍 编码器是将检测对象的运动与相机拍摄取图相匹配的设备,也即检测对象运动一定距离,相机就拍摄一定行高的图像。 编码器会将检测对象的实际位移转换为固定数量电信号。例如:编码器的精度是2000p/r,该参数的含义是编码器每转一圈输…...

【JavaEE】_HTTP响应

目录 1. 首行 2. 报头header 3.空行 4. 正文body 1. 首行 响应首行:版本号状态码状态码描述; HTTP状态码描述了这次响应的结果(比如成功、失败,以及失败原因等); 1. HTTP状态码有: &#…...

SQL防止注入工具类,可能用于SQL注入的字符有哪些

SQL注入是一种攻击技术,攻击者试图通过在输入中注入恶意的SQL代码来干扰应用程序的数据库查询。为了防止SQL注入,你需要了解可能用于注入的一些常见字符和技术。以下是一些常见的SQL注入字符和技术: 单引号 ​: 攻击者可能会尝试…...

【数学建模入门】

数学建模入门 数学建模需要的学科知识怎么学习数学模型如何读好一篇优秀论文数学建模赛题常见类别数学建模常见问题数学建模组队和分工数学建模准备工作 数学建模需要的学科知识 怎么学习数学模型 💦推荐阅读书籍: 《数学建模算法与应用》,…...

ansible剧本中的角色

1 roles角色 1.1 roles角色的作用? 可以把playbook剧本里的各个play看作为一个角色,将各个角色打的tasks任务、vars变量、template模版和copy、script模块使用的相关文件等内容放置在指定角色的目录里统一管理,在需要的时候可在playbook中使…...

weblog项目开发记录--SpringBoot后端工程骨架

知识点查漏补缺 跟着犬小哈做项目实战时发现好多知识点都忘了,还有一些小的知识点可能之前没学过,记录下!顺带整理下开发流程。 完整项目学习见犬小哈实战专栏 SpringBoot后端工程骨架 搭建好的工程骨架中实现了很多基础功能,…...

axios封装终极版实现token无感刷新及全局loading

前言 关于axios全局loading的封装博主已经发过一次了,这次是在其基础上增加了token的无感刷新。 token无感刷新流程 首次登录的时候会获取到两个token(AccessToken,RefreshToken)持久化保存起来(localStorage方案&a…...

推荐一个内网穿透工具,支持Windows桌面、Linux、Arm平台客户端

神卓互联是一款常用的内网穿透工具,它可以将本地服务器映射到公网上,并提供域名或子域名给外部访问。神卓互联具有简单易用、高速稳定的特点,支持Windows桌面版、Linux版、Arm版客户端,以及硬件等。 神卓互联内网穿透技术简介 企…...

【linux】vim多行操作命令

文章目录 1. vim多行同时修改2. vim复制/移动多行3. vim删除多行4. vim设置缩进空格 回顾:vi/vim常用命令 1. vim多行同时修改 (1) ctrl v (2) 按 下箭头,选择多行 (3) shift i,…...

vue-router钩子函数有哪些?都有哪些参数?

Vue.js是一款流行的JavaScript框架,它提供了大量的工具和特性,使得web前端开发更加高效和灵活。其中之一就是Vue-router,它是Vue.js官方路由插件,可以实现前端路由的管理和控制。在使用Vue-router时,我们可以利用钩子函…...

基于JavaWeb开发的小区车辆登记系统计算机毕设[附源码]

基于JavaWeb开发的小区车辆登记系统计算机毕设[附源码] 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统…...

【开源】SpringBoot框架开发高校宿舍调配管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统展示四、核心代码4.1 查询单条个人习惯4.2 查询我的室友4.3 查询宿舍4.4 查询指定性别全部宿舍4.5 初次分配宿舍 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的…...

高压开关柜实现无线测温监测的关键点

一、概述 近年来,电厂自动化、信息化飞速发展,加快了对高压开关柜内的温度检测技术的研究。一系列的开关柜的无线测温监测技术也因此应运而生,并且发挥着越来越重要的作用。高压开关柜是发电厂、变电站、动力车间最重要的电气设备&#xff0c…...

在线图片生成工具:定制化占位图片的利器

title: 在线图片生成工具:定制化占位图片的利器 date: 2024/2/20 14:08:16 updated: 2024/2/20 14:08:16 tags: 占位图片网页布局样式展示性能测试响应式设计在线生成开发工具 在现代的网页设计和开发中,占位图片扮演着重要的角色。占位图片是指在开发过…...

闭包----闭包的理解、优点

1、闭包的理解 闭包就是能够读取其他函数内部变量的函数。 由于在 javascript 中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理 解成 “ 定义在一个函数内部的函数 “ 。 所以,在本质上,闭包是将…...

jenkins的nmp install命令无法下载包

问题:在jenkin的流水线脚本中执行到:npm install命令后无法下载前端依赖包 1、进到jenkins的工作目录,一般在底层为/var/lib/jenkins/workspace/任务名称 cd /var/lib/jenkins/workspace/xkc处理方式: # 查看镜像源 npm config …...

Collection集合体系(ArrayList,LinekdList,HashSet,LinkedHashSet,TreeSet,Collections)

目录 一.Collection 二.List集合 三.ArrayList集合 四.LinkedList集合 五.Set集合 六.hashSet集合 七.LinkedHashSet集合 八.TreeSet集合 九.集合工具类Collections 集合体系概述 单列集合:Collection代表单列集合,每个元素&#…...

AI Agent Runtime 重构:会话即事件日志的工程实践

1. 这不是新赛道,是 runtime 层的“操作系统时刻”来了 你有没有试过让一个 AI 代理连续工作四十分钟?不是闲聊,而是真正在查资料、调 API、写代码、汇总报告——一个接一个步骤往下走。我去年就搭过这么一套系统,用的是当时最火的…...

从靶场搭建到防御加固:一次Hydra爆破Win7 SMB的完整复盘与安全启示

从攻击到防御:SMB协议安全实战分析与加固指南 当一台运行Windows 7系统的计算机暴露在网络中时,它可能正在无声地发出安全警报。SMB协议作为Windows生态中广泛使用的文件共享服务,常常成为攻击者突破内网的第一道门户。本文将从一个真实的渗透…...

HAMi:面向云原生AI基础设施的异构计算统一管理平台

HAMi:面向云原生AI基础设施的异构计算统一管理平台 【免费下载链接】HAMi Heterogeneous GPU Sharing on Kubernetes 项目地址: https://gitcode.com/GitHub_Trending/ha/HAMi 随着AI工作负载在Kubernetes集群中的大规模部署,异构计算资源管理已成…...

从账单明细看Taotoken按Token计费模式如何帮助用户精确定位高消耗场景

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 从账单明细看Taotoken按Token计费模式如何帮助用户精确定位高消耗场景 在构建基于大模型的应用时,成本控制是一个持续性…...

OpenClaw 用户通过 Taotoken 快速接入并启用 Agent 工作流

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 OpenClaw 用户通过 Taotoken 快速接入并启用 Agent 工作流 对于使用 OpenClaw 框架构建 AI Agent 的开发者而言,能够灵…...

毕业答辩效率突围!Paperxie AI 一键搞定高质量毕业论文PPT

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AI PPThttps://www.paperxie.cn/ppt/createhttps://www.paperxie.cn/ppt/create 每一年毕业季,绝大多数高校学生都会陷入同一个困境:论文定稿万事俱备,却卡在了毕业论文答…...

Triton+KServe构建高稳定性AI模型服务架构

1. 项目概述:当模型走出Jupyter,真正开始呼吸真实世界空气“From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题本身就像一句暗号,专为那些在Jupyter里调通了模型、画出了漂亮ROC曲线、却在把模型推上服务器…...

OpenSSH CVE-2024-6387 漏洞原理与实战修复指南

1. 这不是普通补丁:CVE-2024-6387 是 OpenSSH 里埋了二十年的“定时炸弹”你有没有遇到过这种情况:凌晨三点,监控告警疯狂闪烁,SSH 登录失败率突然飙升到98%,但服务器负载、内存、磁盘一切正常;运维同事反复…...

工业级字符识别实战:C#结合YOLO+Tesseract实现药品批号与电子元件丝印精准校验

在工业自动化生产线上,字符识别一直是质量管控的核心环节。从药品包装的批号、有效期到电子元件的丝印型号、批次号,每一个字符的错误都可能导致严重的产品质量问题甚至安全事故。 传统的OCR方案在面对工业场景时往往力不从心:字符倾斜、背景…...

【Coze工作流】零代码做AI自动化,小白也能5分钟上手

一、问题背景:手工做重复AI任务太累,想自动化但不会写代码在日常办公或者内容创作中,很多人都有过这样的痛点:每天要重复打开各种AI工具。比如你要写一篇爆款文章,先要找AI找选题,再让AI写大纲,…...