spring循环依赖的产生与解决
1.循环依赖的产生

在spring中对象默认都是单例的 ,意味整个容器中只有一个该类的对象。
如图,B类有一个属性a,A类有一个属性b。当B类创建对象时,要给a属性赋值;当A类创建对象时,要给b属性赋值,从而产生循环依赖。只要打破当前的闭环,循环依赖就不存在了。
循环依赖产生的根本就是属性赋值。
属性复值的方式有两种:
- 构造器赋值(循环依赖的问题是无法解决的)
- set方法(通过三级缓存来解决)
2.循环依赖的解决
打破当前的闭环,使用三级缓存(三个map集合)解决

半成品: 完成实例化但未完成初始化
成品:完整对象
3.三级缓存问题解析
//源码中的三个的map结构 ,对应的三级缓存
/** Cache of singleton objects: bean name --> bean instance */
//一级缓存,用于保护BeanName和创建bean实例之间的关系
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
//三级缓存,用于保护beanName和创建bean的工厂之间的关系
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name --> bean instance */
//二级缓存,保护beanName和bean实例之间的关系,与singletonFactories的不同之处在于
//当一个单例bean被放到这里之后,那么当bean还在创建过程中就可以通过getbean方法获取到,可以方便进行循环依赖的检测
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

3.1三级缓存中分别保存的是什么对象
1:成品对象
2:半成品对象
3:lambda表达式
3.2如果只使用1级缓存行不行?
不行,因为成品和半成品对象会放到起,在进行对象获取的时候有可能获取到半成品对象,这样的对象是没法使用的
3.3如果只有二级缓存行不行?
getSingleton
doCreateBean
只有二级缓存的时候也可以解决循环依赖的问题,
添加aop的实现之后,报错,This means that said other beans do not use the final version of the bean.没有使用最终版本的bean对象
3.4 三级缓存存在到底做了什么事?
如果一个对象需要被代理,生成代理对象,那么这个对象需要预先生成非代理对象吗? 需要
lambda getEarlyBeanReference().只要搞清楚这个方法的具体执行逻辑即可
在当前方法中,有可能会用代理对象替换非代理对象,如果没有三级缓存的话,那么就无法得到代理对象,换句话说
在整个容器中,包含了同名对象的代理对象和非代理对象,你觉得可以吗?
容器中,对象都是单例的,意味着根据名称只能获取一个对象的值, 此时同时存在两个对象的话,使用的时候应该取哪一个? 无法判断
谁也无法确认什么时候会调用当前对象,是在其他对象的执行过程中来进行调用的,而不是人为指定的,所以必须要保证容器中任何时候都只一
个对象供外部调用,所以在三级缓存中,完整了一件代理对象替换非代理对象的工作, 确定返回的是唯一的对象
三级缓存是为了解决在aop代理过程中产生的循环依赖问题,如果没有aop的话,二级缓存足矣解决循环依赖问题
spring循环依赖的产生与解决的更多相关文章
- Spring循环依赖原因及如何解决
浅谈Spring解决循环依赖的三种方式 SpringBoot构造器注入循环依赖及解决 原文:https://www.baeldung.com/circular-dependencies-in-spri ...
- Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)
本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...
- spring循环依赖是怎么解决的?
回答:循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleA,则它们最终反映为一个环. Spring如何解决循环依赖? ...
- Spring循环依赖的解决
## Spring循环依赖的解决 ### 什么是循环依赖 循环依赖,是依赖关系形成了一个圆环.比如:A对象有一个属性B,那么这时候我们称之为A依赖B,如果这时候B对象里面有一个属性A.那么这时候A和B ...
- 解析spring循环依赖策略
循环依赖 所谓循环依赖就是多个Bean之间依赖关系形成一个闭环,例如A->B->C->...->A 这种情况,当然,最简单的循环依赖就是2个Bean之间互相依赖:A->B ...
- Spring 循环依赖
循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...
- Springboot源码分析之Spring循环依赖揭秘
摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...
- 这个 Spring 循环依赖的坑,90% 以上的人都不知道
1. 前言 这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题.这里权且称他非典型Spring ...
- Spring — 循环依赖
读完这篇文章你将会收获到 Spring 循环依赖可以分为哪两种 Spring 如何解决 setter 循环依赖 Spring 为何是三级缓存 , 二级不行 ? Spring 为啥不能解决构造器循环依赖 ...
随机推荐
- [BJDCTF2020]EzPHP-POP链
那次某信内部比赛中有道pop链问题的题目,我当时没有做出来,所以在此总结一下,本次以buu上复现的[MRCTF2020]Ezpop为例. 题目 1 Welcome to index.php 2 < ...
- 还在用visio?这款画图工具才是真的绝!
最近有读者私信我,问我推文的配图是用什么工具画的,很好看,也想学习一下.今天就给大家介绍一下这款画图工具--Draw.io 概述 draw.io是一款免费的网页版画图工具(也有桌面版),支持流程图.U ...
- XSS-lab通过教程🐶
XSS-lab通过教程 Level-1 payload:http://192.168.33.222:40577/level1.php?name=<script>alert(123)< ...
- linux下玩转磁盘管理与挂载硬盘
前言 本文将带来linux下的磁盘管理中的硬盘挂载,Linux操作系统挂载硬盘需要了解的一些知识.这可能是迄今为止介绍的最最最实用的linux硬盘挂载的文章了,比较详细.由于工作原因,平时使用的比较多 ...
- 2021年SpringBoot面试题200道及答案
https://blog.csdn.net/yanpenglei/article/details/120822218 https://blog.csdn.net/ldb987/article/deta ...
- promise的队列,宏任务,微任务,同步任务
// promise里面有一个特别的任务,就是微任务 // 同步任务>微任务>宏任务 setTimeout(() => { console.log("setTimeout& ...
- gin框架使用Air实时加载
Air实时加载 本章我们要介绍一个神器--Air能够实时监听项目的代码文件,在代码发生变更之后自动重新编译并执行,大大提高gin框架项目的开发效率. 1.1.1. 为什么需要实时加载? 之前使用Pyt ...
- 集合框架-工具类-JDK5.0特性-ForEach循环
1 package cn.itcast.p4.news.demo; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 impo ...
- grafana ldap 权限无法保持
一.Grafana介绍 Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知.它主要有以下六大特点: 1.展示方式:快速灵活的客户端图表,面板插 ...
- Stream流的基本介绍以及在工作中的常用操作(去重、排序以及数学运算等)
平时工作中,我在处理集合的时候,总是会用到各种流操作,但是往往在处理一些较为复杂的集合时,还是会出现无法灵活运用api的场景,这篇文章的目的,主要是为介绍一些工作中使用流时的常用操作,例如去重.排序和 ...