浅谈一下SpringIOC解决循环依赖

新人入住,请多多指点,感觉对您有帮助,请三连~~~,您的这小小举动,是对我最大的鼓励。

1、什么是循环依赖

1.1、官方解释

类A在构造函数中依赖于类B的实例,而类B的构造函数有依赖类A的实例。想这样配置类A和类B相互注入的话,SpringIOC容器会发现这个运行时的循环依赖,并且抛出BeanCurrentlyInCreationException、

1.2、图解

循环依赖是指,A依赖B,B依赖A,他们之间形成一个闭环。如图:

以上就是SpringIOC简单概念介绍,接下来,我们就从Spring源码层级去看下Spring是怎么通过三级缓存去解决循环依赖。


2、三级缓存解决循环依赖


这里的我画了一个流程图,方便新手去查看源码。(会的人可以略过)

入口从这里进

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);

2.1、refresh()方法中一些方法含义

方法名  方法含义
prepareRefresh()准备上下文进行刷新
obtainFreshBeanFactory()  告诉子类刷新内部Bean工厂
prepareBeanFactory()准备在此上下文中使用Bean工厂
postProcessBeanFactroy() 允许在上下文中使用Bean工厂
invokeBeanFactoryPostProcessors()调用Bean工厂的后置处理器
registerBeanPostProcessors()注册Bean工厂的后置处理器
initMessageSource()初始化上下文消息源
initApplicationEventMulticaster()初始化上下文的事件多播
onRefresh()初始化特定上下文子类中的其他特殊Bean
registerListeners()检查监听Bean并注册他们
finishBeanFactoryInitialization()实例化剩余的单例Bean
finishRefresh()最后一步 发布相应的事件

2.2、三级缓存简介

三级缓存名称类型作用
singletonObjectsMap<String,Object>一级缓存,存放完整的Bean
earlySingletonObjectsMap<String,Object>二级缓存,存放早期的Bean,为了判断是否存在循环依赖的关键缓存。
singletonFactoriesMap<String,ObjectFactory<?>>三级缓存。

2.3、三级缓存工作原理

2.4、Spring5.1.x版本与Spring5.3.10版本的区别

看源码,我们能看出来,唯一的区别就是Spring5.3.10版本在加锁前,增加一个从二级缓存中获取一次Bean。

 很明显,spring 在5.3.x版本中,对解决循环依赖的getSingleton方法进行了优化。后面我们再说,这样有什么好处。

我们来看下,classA 和classB的加载过程,如图

根据上面图,我们不难看出,类A在实例化之后,会去缓存中获取BeanA,并将BeanA放到了二级缓存中,然后进行属性赋值,发现A依赖了B,然后B也开始进行实例化B,并将BeanB放到了二级缓存中,然后进行属性赋值,这时发现B依赖A,然后A又开始重复走,当A从缓存获取的时候,从一级缓存是肯定获取不到的,因为BeanA没有初始化成功。然后A从三级缓存中拿出来放入到二级缓存中,然后又进行属性赋值,这时发现A依赖C,然后C又开始doCreateBean,然后C在属性赋值的时候,发现C依赖A,然后A又开始rdoCreateBean,这个时候A已经在二级缓存中了,所以直接从二级缓存中返回Bean。

我所能想到的这个场景能实现Spring5.3.x的优化的思想。

我们发现加锁是一个Synchronized锁,他是一个重量级锁。

3、总结

以上就是SpringIOC在采用三级缓存来解决循环依赖的具体实现。

其实,我们可以看源码能发现,二级缓存其实也足以解决循环依赖的问题,但是网上好多人都在说,三级缓存存在的作用是解决动态代理问题,其实这个说法也有道理。

但是我的理解,你看

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {}

这个接口,我们可以去实现这个接口,然后去重写里面的方法。所以,我觉得,Spring采用三级缓存的作用其实是为了更好的扩展,更好的维护性作用,也是Spring底层源码的设计思想。

乾坤未定,你我皆是黑马!!!!

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值