Spring 是如何解决循环依赖的?

如何解决循环依赖问题?

那Spring到底是如何解决的setter方法依赖注入引起的循环依赖问题呢?请看下图(其实主要是通过两个缓存来解决的):

Spring三大缓存介绍

Spring中有三个缓存,用于存储单例的Bean实例,这三个缓存是彼此互斥的,不会针对同一个Bean的实例同时存储。

推荐:Java进阶视频资源

如果调用getBean,则需要从三个缓存中依次获取指定的Bean实例。读取顺序依次是一级缓存-->二级缓存-->三级缓存

一级缓存:Map<String, Object> singletonObjects

第一级缓存的作用?

  • 用于存储单例模式下创建的Bean实例(已经创建完毕)。
  • 该缓存是对外使用的,指的就是使用Spring框架的程序员。

存储什么数据?

  • K:bean的名称
  • V:bean的实例对象(有代理对象则指的是代理对象,已经创建完毕)

第二级缓存:Map<String, Object> earlySingletonObjects

第二级缓存的作用?

  • 用于存储单例模式下创建的Bean实例(该Bean被提前暴露的引用,该Bean还在创建中)。
  • 该缓存是对内使用的,指的就是Spring框架内部逻辑使用该缓存。
  • 为了解决第一个classA引用最终如何替换为代理对象的问题(如果有代理对象)请爬楼参考演示案例

存储什么数据?

  • K:bean的名称
  • V:bean的实例对象(有代理对象则指的是代理对象,该Bean还在创建中)

第三级缓存:Map<String, ObjectFactory<?>> singletonFactories

第三级缓存的作用?

  • 通过ObjectFactory对象来存储单例模式下提前暴露的Bean实例的引用(正在创建中)。
  • 该缓存是对内使用的,指的就是Spring框架内部逻辑使用该缓存。
  • 此缓存是解决循环依赖最大的功臣

存储什么数据?

  • K:bean的名称
  • V:ObjectFactory,该对象持有提前暴露的bean的引用

为什么第三级缓存要使用ObjectFactory?需要提前产生代理对象。

什么时候将Bean的引用提前暴露给第三级缓存的ObjectFactory持有?时机就是在第一步实例化之后,第二步依赖注入之前,完成此操作。

总结

以上就是Spring解决循环依赖的关键点!总结来说,就是要搞清楚以下几点:

  • 搞清楚Spring三级缓存的作用?
  • 搞清楚第三级缓存中ObjectFactory的作用?
  • 搞清楚为什么需要第二级缓存?
  • 搞清楚什么时候使用三级缓存(添加和查询操作)?
  • 搞清楚什么时候使用二级缓存(添加和查询操作)?
  • 当目标对象产生代理对象时,Spring容器中(第一级缓存)到底存储的是谁?
作者:IT护道师_灭霸詹
来源:http://juejin.cn/post/68957538
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值