处理循环依赖的代码解读

doGetBean 方法


  1. protected <T> T doGetBean( 
  2.   final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) 
  3.   throws BeansException { 
  4.   
  5.   // 从缓存中获取 bean 实例 
  6.  Object sharedInstance = getSingleton(beanName); 
  7.   
  8.    // mbd.isSingleton() 用于判断 bean 是否是单例模式 
  9.    if (mbd.isSingleton()) { 
  10.      // 获取 bean 实例 
  11.     sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 
  12.      @Override 
  13.      public Object getObject() throws BeansException { 
  14.       try { 
  15.         // 创建 bean 实例,createBean 返回的 bean 实例化好的 
  16.        return createBean(beanName, mbd, args); 
  17.       } 
  18.       catch (BeansException ex) { 
  19.        destroySingleton(beanName); 
  20.        throw ex; 
  21.       } 
  22.      } 
  23.     }); 
  24.     // 后续的处理操作 
  25.     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 
  26.    } 
  27.     
  28.  // … 
  29.  
  30.   // 返回 bean 实例 
  31.  return (T) bean; 
  • 按照在源码分析的流程图中可以看到,这一部分是从 getSingleton 先判断是否有实例对象,对于第一次进入是肯定没有对象的,要继续往下走。
  • 在判断 mbd.isSingleton() 单例以后,开始使用基于 ObjectFactory 包装的方式创建 createBean,进入后核心逻辑是开始执行 doCreateBean 操作。

doCreateBean 方法


  1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 
  2.   throws BeanCreationException { 
  3.   
  4.    // 创建 bean 实例,并将 bean 实例包装到 BeanWrapper 对象中返回 
  5.   instanceWrapper = createBeanInstance(beanName, mbd, args); 
  6.   
  7.   // 添加 bean 工厂对象到 singletonFactories 缓存中 
  8.   addSingletonFactory(beanName, new ObjectFactory<Object>() { 
  9.    @Override 
  10.    public Object getObject() throws BeansException { 
  11.      // 获取原始对象的早期引用,在 getEarlyBeanReference 方法中,会执行 AOP 相关逻辑。若 bean 未被 AOP 拦截,getEarlyBeanReference 原样返回 bean。 
  12.     return getEarlyBeanReference(beanName, mbd, bean); 
  13.    } 
  14.   }); 
  15.    
  16.  try { 
  17.    // 填充属性,解析依赖关系 
  18.   populateBean(beanName, mbd, instanceWrapper); 
  19.   if (exposedObject != null) { 
  20.    exposedObject = initializeBean(beanName, exposedObject, mbd); 
  21.   } 
  22.  } 
  23.   
  24.  // 返回 bean 实例 
  25.  return exposedObject; 
  • 在 doCreateBean 方法中包括的内容较多,但核心主要是创建实例、加入缓存以及最终进行属性填充,属性填充就是把一个 bean 的各个属性字段涉及到的类填充进去。
  • createBeanInstance,创建 bean 实例,并将 bean 实例包装到 BeanWrapper 对象中返回
  • addSingletonFactory,添加 bean 工厂对象到 singletonFactories 缓存中
  • getEarlyBeanReference,获取原始对象的早期引用,在 getEarlyBeanReference 方法中,会执行 AOP 相关逻辑。若 bean 未被 AOP 拦截,getEarlyBeanReference 原样返回 bean。
  • populateBean,填充属性,解析依赖关系。也就是从这开始去找寻 A 实例中属性 B,紧接着去创建 B 实例,最后在返回回来。

getSingleton 三级缓存


  1. protected Object getSingleton(String beanName, boolean allowEarlyReference) { 
  2.   // 从 singletonObjects 获取实例,singletonObjects 是成品 bean 
  3.  Object singletonObject = this.singletonObjects.get(beanName); 
  4.  // 判断 beanName ,isSingletonCurrentlyInCreation 对应的 bean 是否正在创建中 
  5.  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { 
  6.   synchronized (this.singletonObjects) { 
  7.     // 从 earlySingletonObjects 中获取提前曝光未成品的 bean 
  8.    singletonObject = this.earlySingletonObjects.get(beanName); 
  9.    if (singletonObject == null && allowEarlyReference) { 
  10.      // 获取相应的 bean 工厂 
  11.     ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); 
  12.     if (singletonFactory != null) { 
  13.       // 提前曝光 bean 实例,主要用于解决AOP循环依赖 
  14.      singletonObject = singletonFactory.getObject(); 
  15.       
  16.      // 将 singletonObject 放入缓存中,并将 singletonFactory 从缓存中移除 
  17.      this.earlySingletonObjects.put(beanName, singletonObject); 
  18.      this.singletonFactories.remove(beanName); 
  19.     } 
  20.    } 
  21.   } 
  22.  } 
  23.  return (singletonObject != NULL_OBJECT ? singletonObject : null); 
  • singletonObjects.get(beanName),从 singletonObjects 获取实例,singletonObjects 是成品 bean
  • isSingletonCurrentlyInCreation,判断 beanName ,isSingletonCurrentlyInCreation 对应的 bean 是否正在创建中
  • allowEarlyReference,从 earlySingletonObjects 中获取提前曝光未成品的 bean
  • singletonFactory.getObject(),提前曝光 bean 实例,主要用于解决AOP循环依赖

综上,是一个处理循环依赖的代码流程,这部分提取出来的内容主要为核心内容,并没有长篇大论的全部拆取出来,大家在调试的时候会涉及的比较多,尽可能要自己根据流程图操作调试几遍。

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章