Spring之循环依赖底层源码解析

目录

一、循环依赖

二、解决循环依赖的思路

1、举例:AServiec依赖BService,BService依赖AService

2、循环依赖的打破

三、三级缓存解析

1、三级缓存的通常叫法:

2、三级缓存详情


一、循环依赖

1、循环依赖:很简单,就是A依赖B,B依赖A。

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

二、解决循环依赖的思路

如何打破这个循环,加入三级缓存。

1、举例:AServiec依赖BService,BService依赖AService

先创建AService,执行AService的生命周期

0、creatingSet<AService>,纪录是否开始创建AService对象的动作;

1、实例化Aservice--->得到一个对象--->singletonFactories<AService,lambda<AService原始对象>>;

2、填充BService属性--->去单例池中寻找BService--->Map--->没有则创建BService;

3、初始化前、初始化;

4、初始化后;

5、放入单例池。

创建BService,执行BService的生命周期

0、实例化BService--->得到一个对象--->Map<BService,BService原始对象>;

1、填充AService属性--->去单例池中找AService--->creatingSet--->出现了循环依赖--->earlySingletonObjects--->sigletonFactories--->lambda--->执行;

2、填充其他属性;

3、初始化前、初始化;

4、初始化后;

5、放入单例池。

2、循环依赖的打破

真正打破循环依赖的是三级缓存,在实例化AService后,得到一个对象,会往singletonFactories<AService,lambda<AService原始对象>>,在创建BService中填充AService属性时,在单例池中没找到AService,通过CreatingSet发现出现了循环依赖,然后会去二级缓存中寻找,二级缓存中没有找到,则在三级缓存中一定能找到,不然如果没找到就需要重新创建AService这样就又是循环依赖了肯定不合理。三级缓存也决定了二级缓存中的对象是原始对象还是代理对象。

三、三级缓存解析

1、三级缓存的通常叫法:

①、一级缓存:sigletonObjects

②、二级缓存:earlySingletonObjects

③、三级缓存:sigletonFactories

2、三级缓存详情

①、sigletonObjects:缓存经过了完整生命周期的bean;

②、earlySingletonObjects:缓存未经过完整生命周期的bean;

③、sigletonFactories:缓存的是一个ObjectFactory,也就是一个lambda表达式。在每个Bean的生成过程中,经过实例化得到一个原始对象,都会提前基于原始对象暴露一个lambda表达式,并保存到三级缓存中。sigletonObjects中,如果当前bean在依赖注入时发现出现了循环依赖,则从三级缓存中拿到lambda表达式,并执行lambda表达式得到一个对象,并把得到的对象放入二级缓存。如果当前Bean需要AOP,那么执行的lambda表达式,得到的就是对应的代理对象,如果无需AOP,则直接得到一个原始对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值