【挑战 Spring】—– Spring之循环依赖一

前言

当你觉得自己很疲惫的时候,别人也很疲惫,你没有理由不逼自己一把!这次说一下Spring中的循环依赖,纯手打+代码调试!及时总结。不然又忘记了!

** 1.什么是循环依赖?**

循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图:

1.png

注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。

项目结构:

2.png

Spring中循环依赖的场景

(1)构造器的循环依赖。(Spring并未解决这种循环依赖的场景问题
(2)field属性的循环依赖。

Spring中Bean实例化的流程

以AService 依赖 BService, BService 依赖AService 举例说明

1. 将AService的class对象解析成BeanDefinition

1.1将该对象标记为create状态,放入一个Map中

2. 利用反射生成 AService对象;

2.1 此时的对象是一个原始对象
2.2将原始对象放入三级缓存的Map中(稍后会在代码中解释)
2.3 放入三级缓存Map中的key:AService, value:一个lambda表达式

3.填充AService对象的属性(也叫依赖注入)

3.1属性中需要bService,会去单例池里面去找
3.2 单例池里面找不到bService,会去二级缓存Map中去找
3.3 二级缓存中仍然找不到bService,则此时会去创建BService对象。(又开始执行第一步将class解析成BeanDefinition以及第2步……)
3.4填充BService对象的属性——>去单例池中寻找AService没找到——>去二级缓存Map中去找——>三级缓存中找—–>找到了lambda表达式(原始对象)—–>执行表达式生成AService—–>执行aop(此时是提前aop)—–>生成aService代理对象—–>放入二级缓存map中<aService,代理对象>—–>三级缓存map.remove(“aService”)删除2.3步中放入Aservice相关信息

4. 执行Aware相关代码(如果BService实现了Aware接口,会回调Aware相关方法)

5.初始化BService对象

6.执行BService的AOP

7.将BService放入单例池

8.如果AService实现了Aware接口,则回调AService的方法.—–>初始化AService对象—–>执行AService的AOP—–>将AService放入单例池

三个缓存的作用

一级缓存:就是Spring的单例池Map

二级缓存: 如果Bean对象提前AOP ,二级缓存存放的是对象的代理对象;如果对象没有提前AOP,二级缓存存放的是原始对象

三级缓存:存放Bean的原始对象的Lambda表达式(如果Bean提前AOP需要依赖原始对象,该原始对象是在三级缓存中获取的)

注意:二级缓存存放了Bean的对象之后,三级缓存中需要把存放的lambda表达式删除掉

代码解读下一篇在解读,代码确实有点绕!

欢迎扫码关注

如果喜欢请关注我公众号【程序倾听者】,说出你的故事!我在这里倾听!

顶我一下下!
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2021 ListenerSun
  • 访问人数: | 浏览次数:

请我吃个棒棒糖可否~

支付宝
微信