Spring的循环依赖是什么?怎么解决

参考周瑜老师教学视频
类之间相互依赖本来是很正常的问题,但是在我们的Spring中就构成一个问题了

因为,在Spring中,一个对象并不是简单new出来了,而是会经过一系列的Bean的生 命周期,就是因为Bean的生命周期所以才会出现循环依赖问题。

当然,在Spring中, 出现循环依赖的场景很多,有的场景Spring自动帮我们解决了,而有的场景则需要程序员来解决,下文详细来说。

1.实例化Aservice

2.给其中的属性赋值,但是我们的Aservice中有一个属性值类型是Bservice(依赖Bservice)

那么首先Spring会先去单例池中去找我们的Bservice,如果找到了就返回,但是找不到就创建Bservice的Bean

​ 开始了Bservice的生命周期

2.1 实例化Bsevice对象

2.2为其中的属性赋值(有Aservice属性),同理单例池中找Aservice的Bean,但是这个时候是找不到的因为 Aservice还没有初始化完的。。。。难道我们的Spring还会继续去新建Aservice么?

一级缓存就是单例池:singletonObjects,是一个map对象

怎么解决?

怎么知道我们要提前AOP呢?

当出现循环依赖的时候,我们就提前进行AOP,那又怎么样判断是否出现循环依赖呢?

实例化对象之前,将我们要实例化的对象放入一个Set中,只要在这个Set中,就说明我们的对象还在实例化,然后继续进行,然后发现Bservice要实例化,也加入到Set中,然后属性填充的时候发现又需要aservice对象,单例池没有,而且我们的Set中有Aservice对象正在创建,就表明是发生了循环依赖,就会进行我们的提前AOP

新的问题,再来个Cservice,也用到了aservice,Aservice中也有Cservice的属性,那我要生成两个Aservice的代理对象么?
不用,这就是我们的二级缓存的工作,earlySingletonObjects,也是一个map,他会判断如果这个map中已经存在了一个Aservice的代理对象,就不会在就AOP了,直接拿过来用,简单来说就是来保证我们的单例特点的(不完整的对象)

然后我们是从我们的二级缓存中拿到我们的对象,放进单例池

那三级缓存是啥呢?
上面还有一个问题,既然我们想要提前AOP,我们就得拿到我们的原始对象(target),怎么拿到这个原始对象呢?

这就需要我们的三级缓存,map对象存储的是<beanName,Aservice原始对象,bean的定义>,这就是我们的三级缓存spring源码 存的是一个lamdba表达式

map.put(beanName,lambda(beanName,BeanDefinition,Aservice原始对象));//拿到Bean的定义,就会知道我们要不要进行AOP

真正的名字是叫做singletonFactorys

为什么一级缓存用的ConcurrentHashMap,而我们的二级三级缓存用的是HashMap呢?

因为二级三级缓存是同时操作的,源码中也体现出来了,我们向二级缓存加beanName就会把三级缓存这个beanName删除掉,在我们用三级缓存加beanName的时候,不管二级缓存有没有也会删除掉二级缓存同一个名字的beanName,就像是一个原子的操作,就算你来用CHashMap也无法保证,所以是在外面的方法加锁了,就没必要用CuHashMap了。

既然我提前AOP了,那后面我就不用AOP了,后面怎么判断我要不要在AOP呢?

有两个方法

getEarlyBeanReference,这个是我们提前AOP走的方法

而且我们发现,这个方法其实就是我们的那个三级缓存中的那个lambda表达式


一个是

postProcessAfterInitialization方法,这个是正常初始化走的AOP方法,这个方法中会去判断:从这个map移除出来一个bean看看是不是原始bean是的话,就说明我们已经提前进行了AOP
这个也是一个map,Cmap用来判断某个类有没有提前进行AOP

几张图来好好理解Spring的循环依赖相关推荐

  1. 图解Spring解决循环依赖

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 来源:juejin.cn/post/684490412216 ...

  2. Spring当中循环依赖很少有人讲,今天让我们来看看吧

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

  3. Spring当中循环依赖很少有人讲,今天一起来学习!

    网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图.流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去 ...

  4. 被问麻了,Spring 如何处理循环依赖?

    点击关注公众号,利用碎片时间学习 前言 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题,在前面Bean实例化流程中,对属性注入一文多多少少对循环依赖有过介绍,这篇文章详细讲一下Spr ...

  5. 【源码分析】Spring的循环依赖(setter注入、构造器注入、多例、AOP)

    写在前面 首先最简单的循环依赖demo就是:A->B 且 B->A.本文围绕这个例子去讲解setter注入的循环依赖.构造器注入循环依赖.多例的循环依赖.带AOP的循环依赖.以下是一些结论 ...

  6. Spring源码剖析-Spring如何处理循环依赖

    前言 你是不是被这个骚气的标题吸引进来的,_ 喜欢我的文章的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力 Spring如何处理循环依赖?这是最近较为频繁被问到的一个面试题, ...

  7. Spring解决循环依赖过程

    依赖注入三种方式 构造器注入 set方法注入 注解方式注入 循环依赖场景 我们知道spring是通过依赖注入(DI)来完成属性的填充,而循环依赖是指实例化两个bean互相依赖对方的情况,比如A依赖B, ...

  8. spring 循环依赖_简单说说 Spring 的循环依赖

    作者 | 田伟然 回首向来萧瑟处,归去,也无风雨也无晴. 杏仁工程师,关注编码和诗词. 前言 本文最耗时间的点就在于想一个好的标题, 既要灿烂夺目,又要光华内敛,事实证明这比砍需求还要难! 由于对象之 ...

  9. Spring IOC循环依赖问题

    Spring IOC循环依赖问题 什么是循环依赖 循环依赖其实就是循环引用, 也就是两个或者两个以上的Bean互相持有对方,形成闭环,例如:A依赖B,B依赖C,C又依赖于A. Spring中循环依赖的 ...

  10. Spring IOC循环依赖

    Spring IOC循环依赖 什么是循环依赖 Spring中Bean实例的创建流程 Spring三级缓存 ClassA创建流程 思考 什么是循环依赖 ClassA中依赖ClassB ClassB中依赖 ...

最新文章

  1. sails框架发送邮件
  2. android输入时背景颜色,Button根据EditText输入状态改变背景颜色
  3. 产品设计体会(8001)产品经理工作手册
  4. 低代码发展专访系列之七:低代码的火爆需要不一样的声音么?
  5. python的repl模式_如何更改sublimeREPL默认python版本
  6. python3未配置_python3安装文件遇到ssl未安装问题
  7. [转载]架构指南 : Java1.7+Eclipse luna + Maven 3.2.5 +spring 4.1.4
  8. java 调用python脚本的方法
  9. 离线安装包_Altium Designer 19.0.14离线安装包
  10. WebService案例实例
  11. 行政区域村级划分数据库_最新行政区划省市区街道乡镇数据库 每月更新版
  12. Django中关于URL配置文件urls.py的理解
  13. eBay Android app 最新,ebay国际版app下载
  14. LWN:GFP 标志介绍以及移除 __GFP_ATOMIC!
  15. 谷歌大规模机器学习:模型训练、特征工程和算法选择 (32PPT下载)
  16. 将 MP3 转成 PCM 并使用 AudioTrack 播放
  17. 物联网发展面临哪些问题
  18. unity 解决乱码_unity3d 中文乱码解决方法——cs代码文件格式批量转化UTF8
  19. 设计模式学习,23种设计模式详解:概述
  20. 情不知所起,一往而深,恨不知所终,纠结流离。

热门文章

  1. matlab转python很难吗_MATLAB在逐渐被Python淘汰吗?
  2. python random random_【python】random与numpy.random
  3. python flag格式_Python 字符串格式化之 printf-style
  4. java对象复制 忽略空值_优秀!高级Java都这样优雅处理空值
  5. mac OS X下终端使用tree命令列目录
  6. 六一儿童节,老师带了很多好吃的巧克力到幼儿园。每块巧克力j的重量为w[j],对于每个小朋友i,当他分到的巧克力大小达到h[i] (即w[j]=h[i]),他才会上去表演节目
  7. Retrofit的使用
  8. Java线程基础(二)
  9. Unity3D学习笔记(三十七):顶点偏移和溶解
  10. 963B:Destruction of a Tree