Spring 是如何解决循环依赖的

10 篇文章 0 订阅

一般想到这个问题,答案就是三级缓存,那么问题又来了,缓存的啥?用啥缓存的?为啥是三级不是二级?

三级缓存指的其实就是三个Map。源码如下图

/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

用白话讲就是,创建三个map,存储对象的三个状态,对于属性依赖(也是最常见的),构造器依赖也是给你抛出错误,实在上并解决不了,为啥解决不了呢?因为一个对象想被引用,他首先得被实例化,所以,如果构造器里存在依赖那就不行了,但属性却可以后续设置, 整体流程如下图:

image-20200723141132352

  1. singletonObjects,一级缓存,存储的是所有创建好了的单例Bean
  2. earlySingletonObjects,二级缓存,完成实例化,但是还未进行属性注入及初始化的对象
  3. singletonFactories,三级缓存,提前暴露的一个单例工厂,二级缓存中存储的就是从这个工厂中获取到的对象

用两级缓存行不行?行

那为什么用三级缓存?

解决代理对象的问题

为啥要解决代理对象的问题,代理对象,就是做个代理,别去访问原对象了,所以,注入的时候,你也应该注入我的代理,啥事也别找我,都找我代理

如果要使用二级缓存解决循环依赖,意味着所有Bean在实例化后就要完成AOP代理,这样违背了Spring设计的原则,Spring在设计之初就是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来在Bean生命周期的最后一步来完成AOP代理,而不是在实例化后就立马进行AOP代理。

所以做个总结就是:

  1. 缓存的啥?各种状态的Bean
  2. 用啥缓存的?Map
  3. 为啥三级?不是二级?见上面
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值