Spring 单例创建流程

19 篇文章 0 订阅
4 篇文章 0 订阅

所有的代码,都只保留了主干流程,为了阅读方便进行了简化处理,具体以源码为准
这里仅供参考
org.springframework.beans.factory.support.AbstractBeanFactory

类图

在这里插入图片描述

单例整体流程

// 通过工厂类,获取对象都是通过这个方法获取的
@Override
public Object getBean(String name) throws BeansException {
   return doGetBean(name, null, null, false);
}

// 删除了不相干的代理,只保留主干
protected <T> T doGetBean(
      final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
      throws BeansException {

    // Eagerly check singleton cache for manually registered singletons.
    // 第一次检查, 从缓存里面取,如果已经存在直接返回, 这里可以
   Object sharedInstance = getSingleton(beanName);
   if (sharedInstance != null) {
       return;
   }
  // Create bean instance.  创建单例
         if (mbd.isSingleton()) {
         
            sharedInstance = getSingleton(beanName, 
              // 使用工厂方法的好处
              // 1, 解偶,创建和使用解偶,使用的地方不需要知道具体的细节
              //   2, 可以根据需要再生成对象,懒生成,而不是每次都生成对象,加快spring启动的速度
              new ObjectFactory<Object>() {
               @Override
               public Object getObject() throws BeansException {
                  try {
                     // 具体创建单例的地方,这例使用就是下面讲解的AbstractAutowireCapableBeanFactory类
                     return createBean(beanName, mbd, args);
                  }
                  catch (BeansException ex) {
                     // Explicitly remove instance from singleton cache: It might have been put there
                     // eagerly by the creation process, to allow for circular reference resolution.
                     // Also remove any beans that received a temporary reference to the bean.
                     destroySingleton(beanName);
                     throw ex;
                  }
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }
   return (T) bean;
}

// 整体的流程控制,保证单例的特性,防止重复生成对象
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "'beanName' must not be null");
   // 加锁,二次检查
   synchronized (this.singletonObjects) {
     Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
          //如果当前单例正在创建中, 如果第二次走到这个地方,就破换了单例的特性,抛出异常
         if (this.singletonsCurrentlyInDestruction) {
            throw new BeanCreationNotAllowedException(beanName,
                  "Singleton bean creation not allowed while singletons of this factory are in destruction " +
                  "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
         }
         // 这个地方很重要,保证了单例的特性,防止重复创建对象
         beforeSingletonCreation(beanName);
         // 创建对象
         singletonObject = singletonFactory.getObject();
         // 缓存对象
         addSingleton(beanName, singletonObject);
      }
      return (singletonObject != NULL_OBJECT ? singletonObject : null);
   }
}

// 判断一个单例是否在创建中
public boolean isSingletonCurrentlyInCreation(String beanName) {
   return this.singletonsCurrentlyInCreation.contains(beanName);
}

// 把单例对象的名称,加入到singletonsCurrentlyInCreation, 同步map]中
// 1, 为了后续的判断是否正在创建单例,
// 2, 防止重复创建对象,破换单例的特性
protected void beforeSingletonCreation(String beanName) {
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
      throw new BeanCurrentlyInCreationException(beanName);
   }
}

创建单例的细节

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. doCreateBean


protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      // 根据构造函数创建对象,如果构造函数有参数,会进行参数的解析,填充
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
   Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
   mbd.resolvedTargetType = beanType;

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            // mbd合并
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }

   // Eagerly cache singletons to be able to resolve circular references
   // even when triggered by lifecycle interfaces like BeanFactoryAware.
   // 单利创建的时候,会先把beanName添加到一个map里面,+ lock,保证单例的特性
   // 只要是单例 所以这里返回true: isSingletonCurrentlyInCreation(beanName) 
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
         // 为了解决循环依赖,单例对象第一次创建完成,会提前发布出去,
         // 使用factory原因的可以进行延迟 生成代理对象
         // 因为循环依赖属于小概率事件,所以注册一个factory,当真的存在循环依赖的时候
         // 再生成真正的对象(spring AOP机制会在这里生成代理对象比较耗时),个人理解所以懒处理的形式,加快速度
   if (earlySingletonExposure) {
      if (logger.isDebugEnabled()) {
         logger.debug("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      addSingletonFactory(beanName, new ObjectFactory<Object>() {
         @Override
         public Object getObject() throws BeansException {
              // Srping AOP在这里进行增强,提前生成代理对象
            return getEarlyBeanReference(beanName, mbd, bean);
         }
      });
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      // 填充参数, @Resource, @Autowired 都是在这里进行处理
      populateBean(beanName, mbd, instanceWrapper);
      if (exposedObject != null) {
         // 初始化对象
         exposedObject = initializeBean(beanName, exposedObject, mbd);
      }
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }
   // 如果提前发布了对象
   if (earlySingletonExposure) {
      // 如果提前发布了对象,但是进行了Spring AOP增强,生成了新的对象,这里需要获取最新的对象,
      // 注意这里的参数是false,不能生成新的对象,只能从缓存里面取
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         if (exposedObject == bean) {
            // 体会为最新生成的对象比如 spring AOP代理对象,保证其单例特性,
            // 如果这里不进行处理会导致循环依赖的对象和当前的对象不一致,破换了单例的特性
            exposedObject = earlySingletonReference;
         }
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
            if (!actualDependentBeans.isEmpty()) {
               throw new BeanCurrentlyInCreationException(beanName,
                     "Bean with name '" + beanName + "' has been injected into other beans [" +
                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                     "] in its raw version as part of a circular reference, but has eventually been " +
                     "wrapped. This means that said other beans do not use the final version of the " +
                     "bean. This is often the result of over-eager type matching - consider using " +
                     "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
            }
         }
      }
   }

   // Register bean as disposable.
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}```

## Spring AOP如何解决,循环依赖的问题,同时保证单例特性
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
类是AOP增强的主流程入口

```bash
// spring 解决单例循环依赖的时候,会提前注册一个BeanFactory,这里会提前生成代理类
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
   Object cacheKey = getCacheKey(bean.getClass(), beanName);
   // 写入这个map的原因,是为了保证单例,这里提前生成了代理类(因为循环依赖),
   // A->B->A , 这种情况下,在创建B的时候,会调用这里提前生成A的代理类,
   // 这个时候B里面的对A的引用已经是新的代理类了,但是A本身的还在初始化的过程中还没完成
   // 需要完成A的初始化,但是还不能重新生成新的代理类否则就不是单例了,所以这里记录
   // 在postProcessAfterInitialization的时候,对比引用,如果一样,就不重新生成代理类了
   // 同时这个方法只会被调用一次,因为单例对象生成过成中会加锁,而且进行缓存,保证创建完成之后
   // 只会从缓存里面取。同时最终A初始化完成之后,会把最终返回的引用对象体会为这里生成的代理对象,保证单例
   this.earlyProxyReferences.put(cacheKey, bean);
   // 生成代理类的具体实现
   return wrapIfNecessary(bean, beanName, cacheKey);
}
// 正常的非循环依赖的对象,都从这里进行AOP的增强
// 这里的循环依赖指的是单例循环依赖(非构造函数依赖)
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      // 1, 如果是循环依赖则remove返回的bean ,和 当前是bean地址一样,这里是false,直接结束
      // 2, 非循环依赖,那这里remove返回的是null,而bean不为空是先决条件,所以这里返回 true,进行类的增强,生成代理类
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         // 生成代理类的具体实现
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值