惊雷无声 发表于 3 天前

Spring为什么要用三级缓存解决循环依赖?

1. Spring是怎样创建一个bean对象


[*] 类
[*] 推断构造方法
默认采用无参构造,假如不存在无参构造,判断有参构造受否唯一,假如唯一选择有参构造,不唯一报错。
[*] 普通对象
[*] 依赖注入
[*] 初始化前(@PostConstruct)
在类中方法上添加@PostConstruct注解,该方法会在初始化前执行。
[*] 初始化(InitializingBean)
类实现InitializingBean接口,重写afterPropertiesSet方法。
[*] 初始化后(AOP)
[*] 署理对象
[*] 放入Map单例池
[*] Bean对象
2. Spring三级缓存

https://i-blog.csdnimg.cn/direct/924a86bea8114c7fa2d84de79f04eed3.png
通太过析源码:
doCreateBean方法
2.1 一级缓存:单例池,履历过完备bean生命,单例Bean对象

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
2.2 二级缓存:提前袒露的Bean

private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
2.3 三级缓存:打破循环

private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//<beanName, 单例创建的工厂>
在创建bean 的源码中先判断是否是单例,支持循环依赖,当前正在创建的单例, 满足上面条件就会创建一个lambda表达式放入三级缓存中。
getEarlyBeanReference方法中会判断是否存在AOP,存在就创建署理对象,不存在就返回通过构造方法创建的普通对象。
https://i-blog.csdnimg.cn/direct/cbcebc7b08be4369aac742d6bcb66a01.png
在三级缓存lambda方法中判断是否创建署理对象
https://i-blog.csdnimg.cn/direct/b1c99e3c175c46a19f9c6addc131f386.png
上边源码中看到只要走三级缓存的会调用getEarlyBeanReference方法,该方法会把执行过AOP的Bean存放在earlyProxyReferences的Map聚集中,用于后续bean生命周期的初始化后是否AOP创建署理对象校验。
https://i-blog.csdnimg.cn/direct/7800b782d3974d40b4f0f0221af0fe88.png
初始化后,校验是否AOP创建署理对象,通过校验earlyProxyReferences聚集中bean是否与传入bean相同来判断。
https://i-blog.csdnimg.cn/direct/c1135f0ee0644382871f18c10bc202fb.png
获取单例bean
https://i-blog.csdnimg.cn/direct/467c35776c1e4d8cb0c40861c122351b.png
3. Spring 解决不了的循环依赖

1.构造器循环依赖(实例化阶段循环依赖) 解决办法添加@Lazy注解
底层原理是创建署理对象,
https://i-blog.csdnimg.cn/direct/702114d9a9234e63886499050358e9a9.png
4.总结

   在Java Spring的厨房里,循环依赖这道菜可是让不少程序员大厨头疼的“暗中料理”。但Spring大厨微微一笑,不慌不忙地亮出了他的秘密武器——三级缓存“韶光机”!
一级缓存,那是“秒出”区,新鲜出炉的Bean直接上桌,快得就像外卖小哥的闪电送。
二级缓存,咱们叫它“半制品天堂”,Bean们在这里稍作休息,等候最后的调味。但别急,好戏还在反面!
重头戏来了,三级缓存——“将来豆预测局”!这里,Spring大厨仿佛拥有了预知将来的超本领,提前把即将诞生的Bean们“画”在纸上,等它们真正诞生时,直接对号入座,无缝衔接。这操作,简直比科幻电影还炫酷!
就如许,Spring大厨用三级缓存的“韶光机”,轻松玩转循环依赖这道困难,让厨房里的Bean们手拉手也能和谐共处,共同烹饪出美味的应用大餐。程序员们纷纷点赞:“Spring大厨,你是我们的超级好汉!”
https://i-blog.csdnimg.cn/direct/7e26eb61ce23414bb5bb7d29e6024286.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Spring为什么要用三级缓存解决循环依赖?