Spring源码解析——IOC之循环依赖处理

打印 上一主题 下一主题

主题 874|帖子 874|积分 2622

什么是循环依赖

循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图所示:

注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。
最全面的Java面试网站
Spring中循环依赖场景有:
(1)构造器的循环依赖
(2)field属性的循环依赖。
对于构造器的循环依赖,Spring 是无法解决的,只能抛出 BeanCurrentlyInCreationException 异常表示循环依赖,所以下面我们分析的都是基于 field 属性的循环依赖。
Spring 只解决 scope 为 singleton 的循环依赖,对于scope 为 prototype 的 bean Spring 无法解决,直接抛出 BeanCurrentlyInCreationException 异常。
如何检测循环依赖

检测循环依赖相对比较容易,Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。
解决循环依赖

我们先从加载 bean 最初始的方法 doGetBean() 开始。
在 doGetBean() 中,首先会根据 beanName 从单例 bean 缓存中获取,如果不为空则直接返回。
  1. protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  2.     Object singletonObject = this.singletonObjects.get(beanName);
  3.     if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  4.         synchronized (this.singletonObjects) {
  5.             singletonObject = this.earlySingletonObjects.get(beanName);
  6.             if (singletonObject == null && allowEarlyReference) {
  7.                 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  8.                 if (singletonFactory != null) {
  9.                     singletonObject = singletonFactory.getObject();
  10.                     this.earlySingletonObjects.put(beanName, singletonObject);
  11.                     this.singletonFactories.remove(beanName);
  12.                 }
  13.             }
  14.         }
  15.     }
  16.     return singletonObject;
  17. }
复制代码
这个方法主要是从三个缓存中获取,分别是:singletonObjects、earlySingletonObjects、singletonFactories,三者定义如下:
[code]private final Map singletonObjects = new ConcurrentHashMap(256);private final Map

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

忿忿的泥巴坨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表