spring 的循环依赖以及spring为什么要用三级缓存解决循环依赖

news2024/11/27 17:40:40

知识铺垫

        bean的生命周期

        这里简单过一下

class ->无参构造 ->普通对象 ->依赖注入(对加了autowire等的属性赋值) ->初始化前->初始化 ->初始化后(aop) ->放入单例池的map(一级缓存) ->bean对象

这里提一点单例bean单例bean 其实就是用map<beanName,Bean对象>创建的,多例bean就不用map

循环依赖

现在有A类和B类,A持有B的引用,B持有A的引用,这就是循环依赖。如果没有Spring,我们又是如何去解决循环依赖呢。注意autowire的内部属性required默认为ture代表这个对象一定要有,不能给他设为null,所有在依赖注入的时候他就一定要有B对象,而B呢一定要有A对象

自己调用自己也算是循环依赖

@Test
	public void testCircle() throws Exception {
		TestA a = new TestA();
		TestB b = new TestB();	
		b.setTestA(a);
		a.setTestB(b);
	}

spring解决循环依赖的原理

spring解决循环依赖也是如此,首先暴露一个未初始化的实例TestA放到缓存中,创建TestB的实例时,获取的是TestA的未初始化对象,TestB创建完成以后,将TestA进行初始化,由于TestB中TestA的引用和TestA是一样的,TestB中的属性也是完全的初始化的

 三级缓存

DefaultSingletonBeanRegistry中存在三个Map,用作三级缓存。
一级缓存:singletonObjects ,用于保存BeanName与创建bean实例。(存放最终的bean)
二级缓存:earlySingletonObjects ,用于BeanName与创建bean实例,与singletonObjects 不同的是earlySingletonObjects 中存放的bean是一个未初始化的bean。(下文有讲解)
三级缓存:singletonFactories ,用于存放BeanName与bean工厂。打破循环
 

/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);

/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);

解决循环依赖就是要打破循环

出现循环依赖了就要提前进行aop

首先我们放在spring容器中的bean是单例的也就是唯一的,当我们出现循环依赖的时候,不如说a b两个类进行了互相调用还交给了spring管理,那么在生程a的时候 回去spring容器中去找b,而此时发现b 还没有创建(此时呢a就被放到了第二级缓存中,属性还没注入呢,就先拿来用了),那么就开始创建b (此时呢 a, 和b只是个普通对象,还没生产bean对象)那么创建b的时候呢,先去singletonObjects 这个map里去找,发现没有(当然创建a的时候们也会先去这去找),在判断a是否在创建,发现a在创建,就去第二级缓存中找,找到了这个a的提前使用的普通对象,就把他那拿到手,为什么这时候不能把他给bean对象呢?按照生命周期应该是这时候成为bean的呀,是因为我们生成的是单例bean 而如果他又aop操作的时候就又会生成代理对象给spring,那这样就不是单例了呀,那么这时候就把aop操作提前,再交给spring。而以上说的这个aop是怎么提前的呢,就是第三级缓存来判断生成额。第三集缓存主要是一个lamada表达式

在这里呢我理解的spring解决循环依赖,其实就是再bean的生命周期时,提前去用生成的这个生成的普通对象,然后最后依赖注入属性值,生成bean对象(其实两级缓存就可以了)

第二级缓存的作用,就是存储那些提前给别人去用的单例bean

三层缓存的关键不是保存前期的bean对象,而是打破循环,其实这个第三级缓存呢就是去打破这个循环的,比如说我们在一个依赖循环中需要一个a,我们在一二级缓存中找不到他的任何bean啊,早期bean啊,这时候我们可以认为这个第三级缓存就是提供这个a的

如果真的找到第三级缓存了,那么他回去判断你要不要aop如果不要aop 我原封不动的把你返回,如果要我返回你的代理对象,然后再放到二级缓存去

必须要第三级缓存判断aop,而且进入第三级缓存没有附加的条件去判断近不近,只要从第二级找不着,就进入三级缓存

 如何去判断某个bean有没有提前进行aop这样你初始化后就不会了

这两个图中的字段

 解决不了的依赖注入

 

 

 这样的循环解决不了,这是在实例化的时候就出现了循环依赖,连对象都创建不了,咋办不行呗

他这个构造方法的过,你构造a的时候需要b,而你构造b的时候需要a。加个空参构造是可以的。

用@lazy 能解决吗

 加了lazy,spring会直接给生成一个代理对象,跟aop没关系

至此结束,关于lazy如何生成代理对象,肥春本章不做讲解

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

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

相关文章

第二次作业 运维高级 MySQL主从复制

1.理解MySQL主从复制原理 1、master&#xff08;binlog dump thread&#xff09;主要负责Master库中有数据更新的时候&#xff0c;会按照binlog格式&#xff0c;将更新的事件类型写入到主库的binlog文件中。 2、I/O thread线程在Slave中创建&#xff0c;该线程用于请求Master&…

有些能力,是工作中学不来的,看看这篇超过90%同行

俗话说:360行&#xff0c;行行转IT。 在就业形势压力巨大的今天&#xff0c;不仅仅是计算机专业的毕业生&#xff0c;很多其他专业的大学生都选择转行从事计算机行业。 尤其是软件测试行业&#xff0c;远远超出其他行业的薪水和广阔的就业前景&#xff0c;吸引了大批应届毕业…

PostgreSQL——Windows上安装PostgreSQL

下载地址&#xff1a;PostgreSQL下载网址 因为某些问题我自己安装的是postgresql-11.2-1-windows-x64 根据下图顺序安装即可&#xff0c;不同版本可能顺序有点区别但每部分目的都是一样的。 首先右键以管理员身份运行&#xff0c;可以弹出安装界面

多通道振动信号经小波变换成多通道信息融合的图像(Python编程)

1.数据集介绍&#xff1a;凯斯西楚大学轴承数据集&#xff08;12KHZ采样频率下&#xff0c;四种不同负载数据集&#xff09; 2.这里以0HP文件夹为例&#xff0c;进行展示&#xff0c;有内圈故障&#xff0c;正常&#xff0c;外圈故障和滚动体故障四个文件夹 内圈故障文件夹下有…

【2023周报】week23 eBPF学习

week23 eBPF学习 如何调试eBPF程序&#xff1f; bpf SystemCall [bpf(2) - Linux manual page (man7.org)](https://man7.org/linux/man-pages/man2/bpf.2.html) [bpf-helpers(7) - Linux manual page (man7.org)](https://man7.org/linux/man-pages/man7/bpf-helpers.7.htm…

Python基本语法之符号使用

好久没有和小伙伴们更新python了&#xff0c;我对于此感到抱歉以后有时间尽量多更新 目录 一. 标识符 A.定义&#xff1a; B.使用特点 C.Python标识符&#xff0c;进一步探讨以下几个方面的详细内容&#xff1a; 1. 规则和约定&#xff1a; 2. 有效的标识符示例&#xff1…

【LeetCode每日一题】——剑指 Offer II 027.回文链表

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【题目进阶】八【题目注意】九【解题思路】十【时间频度】十一【代码实现】十二【提交结果】 一【题目类别】 栈 二【题目难度】 简单 三【题目编号】 剑指 Offer II 02…

3.1flex布局

参考链接 MDN 核心组成 容器 容器指定元素item的布局方式 元素 元素自定义自身的宽度大小

高数笔记02:导数、微分、中值定理

图源&#xff1a;文心一言 本文是我学习高等数学第二、三章导数、微分、中值定理的一些笔记和心得&#xff0c;希望可以与考研路上的小伙伴一起努力上岸~~&#x1f95d;&#x1f95d; 第1版&#xff1a;查资料、画导图、归纳题型~&#x1f9e9;&#x1f9e9; 参考用书1&…

Tomcat修改端口号

网上的教程都比较老&#xff0c;今天用tomcat9.0记录一下 conf文件夹下server.xml文件 刚开始改了打红叉的地方&#xff0c;发现没用&#xff0c;改了上面那行

SpringBoot整合第三方 Druid、MybatisPlus、Mybatis

整合第三方技术 整合JUnit Respostory 注解&#xff1a;数据类 1、导入测试对应的starter 2、测试类使用 SpringBootTest 修饰 3、使用自动装配的形式添加要测试的对象 classes的属性 其实主要找的是SpringBootApplication中的SpringBootConfiguration这个注解。也就是配置…

【Axure高保真原型】标准金额格式输入框

今天和大家分享标准金额格式输入框的原型模板&#xff0c;在输入框里输入数字后&#xff0c;会自动将对应的数字转为标准金额格式输入&#xff0c;自动添加千分位&#xff0c;例如输入2000&#xff0c;输入内容为2,000.00。具体效果可以观看下方视频或者打开预览地址体验 【原…

三星发布新智能手表:旋转边框回归,Galaxy Watch6 系列震撼来袭

今晚&#xff0c;三星发布了最新的Galaxy Watch6系列智能手表&#xff0c;其中包括Galaxy Watch6和Watch6 Classic两款。Watch6 Classic再次引入了三星手表所独有的旋转边框特色。这两款手表提供多种尺寸和支持LTE的版本&#xff0c;同时还搭载了内置的eSIM模块&#xff0c;为用…

Cookie简介

Cookie使用场景 在接口测试过程中&#xff0c; 很多情况下&#xff0c;需要发送的请求附带cookies&#xff0c;才能返回正常的结果。所以在使用pythonrequests进行接口自动化测试也是同理&#xff0c; 需要在构造接口测试用例时加入cookie。 传递Cookie的两种方式&#xff1a…

TortoiseSVN-1.14.5.29465-x64-svn-1.14.2的安装包以及汉化包

TortoiseSVN-1.14.5.29465-x64-svn-1.14.2的安装包以及汉化包 为了存一手这个安装包 CSDN资源地址&#xff0c;0积分 https://download.csdn.net/download/lu6545311/88085035 包内内容&#xff0c;一个安装包&#xff0c;一个汉化包 如果你想在你的编辑器&#xff0c;比如v…

Span-based Named Entity Recognitionby Generating and Compressing Information

原文链接&#xff1a;https://aclanthology.org/2023.eacl-main.146.pdf EACL 2023 介绍 对于information bottleneck (IB) principle信息瓶颈原理&#xff0c;要么使用生成模型&#xff0c;要么使用信息压缩模型来提高在目标任务上的性能&#xff0c;因此作者将这两种模型进行…

SpringMVC框架搭建

SpringMVC框架搭建 快速开启SpringMVC&#x1f680;&#x1f680; 步骤 1、新建模块 2、引入相关依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.1</version> &…

科大讯飞-旋转机械故障诊断挑战赛2023-测试【1】

引言 旋转机械故障诊断挑战赛是一项旨在提高旋转机械故障检测和识别能力的竞赛活动。旋转机械是工业生产中广泛应用的设备&#xff0c;其运行状态直接影响着生产效率和安全性。然而&#xff0c;由于各种原因&#xff0c;旋转机械可能会出现不同类型的故障&#xff0c;如轴承损坏…

玩转Python 秒懂python

解析器&#xff1a; 数据结构&#xff1a; 变量运算&#xff1a; 文件处理&#xff1a; 输入输出&#xff1a; 异常处理&#xff1a; 函数模块&#xff1a; 面向对象&#xff1a; 多线程&#xff1a; 三方库&#xff1a;

菜鸡shader:L13 渐隐渐显的UV动画

文章目录 SD部分Shader代码部分 呃呃&#xff0c;这是目前我学习庄懂AP01课程的最后一节了&#xff0c;我看了一下21集之后的内容是关于LightingMap&#xff0c;目前感觉还用不到&#xff0c;加上之前参与过一个项目里面也有用到LightingMap&#xff0c;也算了解过&#xff0c;…