源码级详解Spring的三级缓存,循环依赖的处理流程

一.什么是三级缓存

1.一级缓存:存放已经初始化完成的Bean

2.二级缓存:存放半成品Bean,既实例化完成未初始化的Bean。

3.三级缓存:存放bean工厂

二.为什么是三级缓存

一级缓存是必须的,这个我们没有什么疑问。那为什么要有二级缓存,二级缓存主要是用来解决循环依赖的问题。

2.1什么是循环依赖

循环依赖就是指循环引用,是两个或多个Bean相互之间的持有对方的引用。

举个简单的例子:

kotlin
复制代码@Service
public class AService {

    @Resource
    private BService bService;
}
kotlin
复制代码@Service
public class BService {


    @Resource
    private AService aService;
}

AService中依赖了BService,而BService又依赖了AService,这样就构成循环依赖。

Spring是允许单例bean进行循环依赖的。

2.2循环依赖的bean注入流程

下面我就带大家从源码的层面,讲解三级缓存是如何解决循环依赖问题的。

1.doCreateBean方法会调用createBeanInstance方法来对beanA进行实例化。

2.addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));会将生成代理对象的工厂放入到三级缓存。

3.beanA调用populateBean方法,注入beanB实例。

在注入beanB实例的过程中,发现beanB依赖了beanA,需要将beanA加载出来。

会再次对beanA调用doGetBean方法。这时候,getSingleton方法就真正派上用场了。

4.在getSingleton方法中,会将beanA的bean工厂从三级缓存中取出来,调用getObject方法,也就是getEarlyBeanReference方法,将返回结果放入二级缓存,同时从三级缓存移除掉。

5.把不完整的beanA注入到beanB中

6.beanB执行addSingleton(beanName, singletonObject)方法,这个方法将beanB放入到一级缓存,且从二级缓存中移除掉。

7.beanA注入beanB实例。

8.beanA完成属性填充和初始化,执行addSingleton(beanName, singletonObject)方法,将BeanA放入到一级缓存。

从上面注入的流程,可以看出,如果没有存放半成品的二级缓存,那么循环依赖是无法解决的。如果我们在实例化完beanA,立刻创建出代理对象放到二级缓存,再填充beanA的属性以及初始化,这样也可以正常完成BeanA,BeanB的注入。这样就省掉了第三级缓存。那第三级缓存存在的原因是什么呢?

2.3.第三级缓存在的原因

要理清楚,三级缓存存在的原因主要原因有两个,一是因为AOP,二是循环依赖。如果没有Spring AOP和循环依赖,那么就不需要使用三级缓存。

我们先看下,不存在循环依赖的代理对象是如何生成的?

上图第五步的时候,会调用AbstractAutoProxyCreator类的
postProcessAfterInitialization方法,创建代理对象。对于不涉及到循环依赖的bean,会在初始化之后,创建代理对象。

而对于涉及到循环依赖的bean,如果没有三级缓存,在对象实例化后,就要立刻生成其代理对象,这样会影响到bean注入整个代码的逻辑。增加三级缓存,一可以防止循环依赖的对象多次被代理还可以做到循环引用的bean,在被循环引用时,代理对象被创建且注入进去,不涉及到循环引用的bean,等到初始化之后创建代理对象。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第6章:知识建模:概述、方法、实例

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…

后缀数组模板

详细理解后缀数组求sa数组的函数,该函数可以看为主要分为三个部分,第一个部分是预处理;第二个部分是进行基数排序,首先根据第二关键词排序,然后根据第一关键字排序;第三个部分是根据排序后的结果重新为每个…

等保二级和三级的区别

等保二级和三级定级标准有什么区别?定级原则和方法介绍 网络安全等级保护,简称等保,是我国为了保障信息系统的安全运行,防止信息泄露、篡改、破坏等威胁,制定的一套信息安全管理制度。根据《信息安全技术网络安全等级保…

6.21二叉搜索树的最近公共祖先(L235-M)

算法: 可以和上一题一样做,但是最好还是要用上二叉搜索树的特性 遍历顺序无所谓,因为中不用写逻辑代码。 假如p3,q5 若当前遍历节点(比如6)比p和q都大,说明p和q一定在当前节点的左子树里面 …

Python数值类型(整形、浮点型和复数)及其用法

数值类型是计算机程序最常用的一种类型,既可用于记录各种游戏的分数、游戏角色的生命值、伤害值等,也可记录各种物品的价格、数量等,Python 提供了对各种数值类型的支持,如支持整型、浮点型和复数。 Python整型 Python 3 的整型…

Intel® Enclave Operation(三)

文章目录 前言一、Constructing an Enclave1.1 ECREATE1.2 EADD and EEXTEND Interaction1.3 EINIT Interaction1.4 Intel SGX Launch Control Configuration 二、Enclave Entry and Exiting2.1 Controlled Entry and Exit2.2 Asynchronous Enclave Exit (AEX)2.3 Resuming Exe…

web服务器之——建立两个基于ip地址访问的网站

目录 准备工作:web服务器搭建 第一步:挂载 第二步:编辑配置文件 第三步:安装软件包 第四步:启动httpd 查看配置文件: 第五步:设置防火墙状态: 重启服务: 查看状态&#xff1…

自己开发App,如何能兼顾效率与体验?

今天来聊聊一个现实但不简单的问题:如何能够做到自己开发App。 首先,在搜索引擎搜索“自己开发App”,会冒出一大堆类“手把手”的内容,超级详细、稍微浏览一些内容的引言部分,乍一看好像还挺合理,但点击进…

多地远程视频监控,如何集中连接与管理?

如今,远程视频监控已广泛应用于商超零售、酒店、工厂工地、IT机房、农业生产、医疗保健、公共安全等多种场景。其中,网络通信技术是远程监控技术中最为关键的技术,远程监控数字化应用的增长对广域网等基础IT建设提出更高的需求。 以广东某连锁…

python实战教学之python版“张万森,好久不见”

前言 WINTER IS COMING 最近《一闪一闪亮星星》的电影在火热预售中,家人们抢到票了嘛,前两天小编写了一篇“张万森,下雪了”的文章后,收到了不少小伙伴的反馈:“代码的运行结果只有文字,没有雪花啊”&#…

气温波动 C语言xdoj45

问题描述 最近一段时间气温波动较大。已知连续若干天的气温,请给出这几天气温的最大波动值是多少,即在这几天中某天气温与前一天气温之差的绝对值最大是多少。 输入说明 输入数据分为两行。 第一行包含了一个整数n,表示给出了连续n天…

JNPF低代码——全源码、免费部署的开发框架

低代码平台的概念很火爆,产品也是鱼龙混杂。 对于开发人员来说,在使用绝大部分低代码平台的时候都会遇到一个致命的问题:我在上面做的项目无法得到源码,完全黑盒。一旦我的需求平台满足不了,那就是无解。 与其他平台的…

便签电脑版下载教程,电脑便签用哪个

现在大家所熟知的电脑便签软件通常以电脑软件为主,过去那种贴满五颜六色的,几百张成一叠的桌面便利贴,可以实现随处粘贴,现在几乎已经被淘汰了,取而代之的是科技化的电脑便签软件。 在查找电脑便签软件时,…

helpdesk的工作流程是什么?

helpdes在IT部门中是一个非常重要的部门,负责为用户提供技术支持和问题解决方案。为了有效地提供这些服务,helpdesk需要建立一个清晰而高效的工作流程。本文将介绍helpdesk工作的典型流程,并探讨每个阶段的重要性。 1、用户报告问题 通常&…

RCG Self-conditioned Image Generation via Generating Representations

RCG: Self-conditioned Image Generation via Generating Representations TL; DR:将图像的无监督表征作为(自)条件(而非是将文本 prompt 作为条件),生成与原图语义内容一致的多样且高质量结果。视觉训练能…

Android :Paging (分页)加载数据-简单应用

1.Paging介绍: 安卓Paging是一种分页加载数据的方法,它基于无限滚动模式而设计,可以帮助应用更高效地利用网络带宽和系统资源。Paging库可以加载和显示来自本地存储或网络中更大的数据集中的数据页面,适用于以列表的形式加载大量…

VSCode配置记录

1. 修改代码背景颜色 1)Shift Command P,搜索框输入:settings.json 2)输入配置 {"workbench.colorCustomizations": {"editor.lineHighlightBackground": "#86e9e93d", # 修改鼠标所在行背景色…

自动化测试 —— Web自动化三大报错

Web自动化三大报错有哪些呢?接下来给大家讲讲。 Web自动化三大报错(Exception) 1. Exception1:no such element(没有在页面上找到这个元素) reason1:元素延迟加载了 solution: …

功率放大器有哪些功能和作用

功率放大器是一种电子设备,主要用于将输入的低功率信号放大为更大的功率信号。功率放大器的主要功能和作用包括: 信号放大:功率放大器可以将输入的低功率信号放大为更大的功率信号。这对于一些需要输出更大功率的应用来说非常重要&#xff0c…

外包干了3年,技术退步太明显了。。。。。

先说一下自己的情况,本科生生,18年通过校招进入武汉某软件公司,干了差不多3年的功能测试,今年国庆,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能…