源码级详解Spring的三级缓存,循环依赖的处理流程

2022-12-15 程序员资讯 0 970
¥ 2.88B

包年VIP免费升级包年VIP

开通VIP尊享优惠特权
立即下载 升级会员

源码级详解Spring的三级缓存,循环依赖的处理流程

一.甚么是二级内存

1.二级内存:放置早已调用顺利完成的Bean

2.二级内存:放置成品Bean,既示例化顺利完成未调用的Bean。

3.二级内存:放置bean厂房

二.为甚么是二级内存

二级内存是要的,那个我们没甚么疑点。那为甚么要有二级内存,二级内存主要就是用以化解循环式倚赖的难题。

2.1甚么是循环式倚赖

循环式倚赖即是循环式提及,是三个或数个Bean彼此之间的所持旁人的提及。

举个单纯的范例:

@Service public class AService { @Resource private BService bService; }@Service public class BService { @Resource private AService aService; }

AService中倚赖了BService,而BService又倚赖了AService,这种就形成循环式倚赖。

Spring是容许科枫bean展开循环式依赖的。

2.2循环式倚赖的bean转化成业务流程

源码级详解Spring的三级缓存,循环依赖的处理流程

下面我就带大家从源代码的层面,讲解二级内存是如何化解循环式倚赖难题的。

1.doCreateBean方法会调用createBeanInstance方法来对beanA展开示例化。

2.addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));会将生成代理对象的厂房放入到二级内存。

3.beanA调用populateBean方法,转化成beanB示例。

在转化成beanB示例的过程中,发现beanB倚赖了beanA,需要将beanA加载出来。

会再次对beanA调用doGetBean方法。这时候,getSingleton方法就真正派上用场了。

4.在getSingleton方法中,会将beanA的bean厂房从二级内存中取出来,调用getObject方法,也就是getEarlyBeanReference方法,将返回结果放入二级内存,同时从二级内存移除掉。

5.把不完整的beanA转化成到beanB中

6.beanB执行addSingleton(beanName, singletonObject)方法,那个方法将beanB放入到二级内存,且从二级内存中移除掉。

7.beanA转化成beanB示例。

8.beanA顺利完成属性填充和调用,执行addSingleton(beanName, singletonObject)方法,将BeanA放入到二级内存。

从上面转化成的业务流程,可以看出,如果没放置成品的二级内存,那么循环式倚赖是无法化解的。如果他们在示例化完beanA,立刻创建出代理对象放到二级内存,再填充beanA的属性以及调用,这种也可以正常顺利完成BeanA,BeanB的转化成。这种就省掉了第二级内存。那第二级内存存在的原因是甚么呢?

2.3.第二级内存在的原因

要理清楚,二级内存存在的原因主要就原因有三个,一是因为AOP,二是循环式倚赖。如果没Spring AOP和循环式倚赖,那么就不需要使用二级内存。

他们先看下,不存在循环式倚赖的代理对象是如何生成的?

源码级详解Spring的三级缓存,循环依赖的处理流程

上图第五步的时候,会调用AbstractAutoProxyCreator类的

postProcessAfterInitialization方法,创建代理对象。对于不涉及到循环式倚赖的bean,会在调用之后,创建代理对象。

而对于涉及到循环倚赖的bean,如果没二级内存,在对象示例化后,就要立刻生成其代理对象,这种会影响到bean转化成整个代码的逻辑。增加二级内存,一可以防止循环式倚赖的对象多次被代理还可以做到循环式提及的bean,在被循环式提及时,代理对象被创建且转化成进去,不涉及到循环式提及的bean,等到调用之后创建代理对象。

喜欢源代码的朋友关注点赞,后续会分享更多干货。

资源下载此资源下载价格为2.88B,包年VIP免费,请先
2405474279

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务