1.循环依赖的产生

在spring中对象默认都是单例的 ,意味整个容器中只有一个该类的对象。

如图,B类有一个属性a,A类有一个属性b。当B类创建对象时,要给a属性赋值;当A类创建对象时,要给b属性赋值,从而产生循环依赖。只要打破当前的闭环,循环依赖就不存在了。

循环依赖产生的根本就是属性赋值。

 属性复值的方式有两种:

  1. 构造器赋值(循环依赖的问题是无法解决的)
  2. 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循环依赖的产生与解决的更多相关文章

  1. Spring循环依赖原因及如何解决

    浅谈Spring解决循环依赖的三种方式 SpringBoot构造器注入循环依赖及解决 原文:https://www.baeldung.com/circular-dependencies-in-spri ...

  2. Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)

    本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...

  3. spring循环依赖是怎么解决的?

    回答:循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleA,则它们最终反映为一个环. Spring如何解决循环依赖? ...

  4. Spring循环依赖的解决

    ## Spring循环依赖的解决 ### 什么是循环依赖 循环依赖,是依赖关系形成了一个圆环.比如:A对象有一个属性B,那么这时候我们称之为A依赖B,如果这时候B对象里面有一个属性A.那么这时候A和B ...

  5. 解析spring循环依赖策略

    循环依赖 所谓循环依赖就是多个Bean之间依赖关系形成一个闭环,例如A->B->C->...->A 这种情况,当然,最简单的循环依赖就是2个Bean之间互相依赖:A->B ...

  6. Spring 循环依赖

    循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...

  7. Springboot源码分析之Spring循环依赖揭秘

    摘要: 若你是一个有经验的程序员,那你在开发中必然碰到过这种现象:事务不生效.或许刚说到这,有的小伙伴就会大惊失色了.Spring不是解决了循环依赖问题吗,它是怎么又会发生循环依赖的呢?,接下来就让我 ...

  8. 这个 Spring 循环依赖的坑,90% 以上的人都不知道

    1. 前言 这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题.这里权且称他非典型Spring ...

  9. Spring — 循环依赖

    读完这篇文章你将会收获到 Spring 循环依赖可以分为哪两种 Spring 如何解决 setter 循环依赖 Spring 为何是三级缓存 , 二级不行 ? Spring 为啥不能解决构造器循环依赖 ...

随机推荐

  1. 【SpringCloud技术专题】「Gateway网关系列」(3)微服务网关服务的Gateway全流程开发实践指南(2.2.X)

    开发指南须知 本次实践主要在版本:2.2.0.BUILD-SNAPSHOT上进行构建,这个项目提供了构建在Spring生态系统之上API网关. Spring Cloud Gateway的介绍 Spri ...

  2. python2.7发送邮件失败之——邮箱安全问题

    使用python2.7发送邮件,通过脚本调试,脚本运行通过成功发出了邮件,但是目标邮箱qq没有收到. 刚开始怀疑脚本问题,上网查找资料后,发现邮箱发送成功后目标邮件没有收到有可能有以下几种原因: 1. ...

  3. 【记录一个问题】铁威马nas,噪音太大了,我老婆说在客厅放了一个电饭锅

    1.硬盘转动的噪音特别大,而且还是有很大IO的长时间猛转: 2.IO的管理算法,以及做IO的进程,都有很大问题.并未做任何操作,动不动就疯了一样硬盘猛转.

  4. Choregraphe 2.8.6.23动作失效

    动作和动画执行完以后,无法自动还原成默认状态,自然接下来动作无法执行了.之后各种操作可能诱发软件原有的bug.需要开关自主生活模块才能恢复. 部分连贯的动作不需要恢复就能执行,动画不行. 站立动作好像 ...

  5. NIO-java.nio.ByteBuffer中flip、rewind、clear方法的区别

    Java NIO中的Buffer用于和NIO通道进行交互.如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的. 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.这块内存被包装成NIO ...

  6. golang中int、float、string数据类型之间的转换

    package main import ( "fmt" "strconv" ) func main() { var num1 int = 88 var num2 ...

  7. 直接copy大于某一个时间小于某一个时间的文件--find进阶用法

    find ./ -type f -newermt '2000-01-04 10:30:00' ! -newermt '2019-10-28 10:57:00' -exec cp -a {} /var/ ...

  8. python利用正则表达式提取文本中特定内容

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python ...

  9. 来自开发者的点赞!HMS Core荣获多个行业奖项

    2021年,HMS Core发布全新HMS Core 6,为全球开发者提供多终端.跨OS.全场景的华为移动服务核心能力,和开发者共同成长.通过和开发者在行业解决方案.业务场景创新和商业增长上的持续合作 ...

  10. SpringBoot Log4j 安全漏洞分析及解决方案

    一.序言 SpringBoot作为Java基础框架大行其道,前不久爆发出Log4j安全漏洞,大众更多关心Log4j的危害是多么严重,然而鲜有关心SpringBoot这一底层框架的安全性问题,换而言之, ...