SpringIOC refresh()初始化代码实例

2020-03-06 18:01:44王旭

getBean(beanName):Bean初始化

/* org/springframework/beans/factory/support/AbstractBeanFactory.java:414 */
  protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    //如果是aliaName,解析成beanName
    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    //检查单例缓存中是否存在bean的实例化对象、初始化对象 (涉及循环依赖解决,需要先分清出Bean的两个阶段实例化、初始化)
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
      if (logger.isTraceEnabled()) {
        if (isSingletonCurrentlyInCreation(beanName)) {
          logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
              "' that is not fully initialized yet - a consequence of a circular reference");
        }
        else {
          logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
        }
      }
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
      if (isPrototypeCurrentlyInCreation(beanName)) {
        //多例bean正在初始化时抛出异常
        //由于多例bean,每调用一次getBean就会创建一个实例,
        //所以通过ThreadLocal打标,来避免单个线程的重复创建
        throw new BeanCurrentlyInCreationException(beanName);
      }

      BeanFactory parentBeanFactory = getParentBeanFactory();
      //父容器不为空,用父容器初始化
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        // Not found -> check parent.
        String nameToLookup = originalBeanName(name);
        if (parentBeanFactory instanceof AbstractBeanFactory) {
          return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
              nameToLookup, requiredType, args, typeCheckOnly);
        }
        else if (args != null) {
          // Delegation to parent with explicit args.
          return (T) parentBeanFactory.getBean(nameToLookup, args);
        }
        else if (requiredType != null) {
          // No args -> delegate to standard getBean method.
          return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
        else {
          return (T) parentBeanFactory.getBean(nameToLookup);
        }
      }

      if (!typeCheckOnly) {
        //alreadyCreated容器记录已经被实例化的beanName,
        //这里将beanName添加到alreadyCreated
        markBeanAsCreated(beanName);
      }

      try {
        //重新获取mergedLocalBeanDefinition(bean与parentBean合并)
        final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        //检查mbd不是抽象类
        checkMergedBeanDefinition(mbd, beanName, args);

        //创建bean单例之前,需要保证先bean所依赖的Bean单例已创建,
        //这里的依赖对应@dependsOn声明的依赖,这个注解不常用,这里也会出现一种循环依赖场景,与我们平常讨论的引用循环依赖不同
        //@dependsOn(value = "b") class A;@dependsOn(value = "a") class B
        //如果出现这种循环依赖 会直接抛出异常 启动失败
        String[] dependsOn = mbd.getDependsOn();
        if (dependsOn != null) {
          for (String dep : dependsOn) {
            if (isDependent(beanName, dep)) {
              throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
            }
            //保存依赖关系到dependentBeanMap容器中
            registerDependentBean(dep, beanName);
            try {
              //实例化依赖的bean 这里就是常见循环依赖地点 A依赖B B依赖A
              getBean(dep);
            }
            catch (NoSuchBeanDefinitionException ex) {
              throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
            }
          }
        }

        // Create bean instance.
        if (mbd.isSingleton()) {
          //单例Bean创建 先取缓存,没有才createBean
          sharedInstance = getSingleton(beanName, () -> {
            try {
              //创建Bean实例
              return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
              destroySingleton(beanName);
              throw ex;
            }
          });
          bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }

        else if (mbd.isPrototype()) {
          //多例Bean创建 直接createbean
          Object prototypeInstance = null;
          try {
            //正在创建bean打标prototypesCurrentlyInCreation
            //与上面isPrototypeCurrentlyInCreation()联合
            beforePrototypeCreation(beanName);
            prototypeInstance = createBean(beanName, mbd, args);
          }
          finally {
            //正在创建bean打标prototypesCurrentlyInCreation删除标记
            afterPrototypeCreation(beanName);
          }
          bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
        }

        else {
            //自定义scope初始化、scope.get()
          String scopeName = mbd.getScope();
          final Scope scope = this.scopes.get(scopeName);
          if (scope == null) {
            throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
          }
          try {
            Object scopedInstance = scope.get(beanName, () -> {
              beforePrototypeCreation(beanName);
              try {
                return createBean(beanName, mbd, args);
              }
              finally {
                afterPrototypeCreation(beanName);
              }
            });
            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
          }
          catch (IllegalStateException ex) {
            throw new BeanCreationException(beanName,
                "Scope '" + scopeName + "' is not active for the current thread; consider " +
                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                ex);
          }
        }
      }
      catch (BeansException ex) {
        cleanupAfterBeanCreationFailure(beanName);
        throw ex;
      }
    }
//getBean(beanName,requiredType)时检查创建的实例是否需要的类型,容器初始化时不会走进里面
    if (requiredType != null && !requiredType.isInstance(bean)) {
      try {
        T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
        if (convertedBean == null) {
          throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
        return convertedBean;
      }
      catch (TypeMismatchException ex) {
        if (logger.isTraceEnabled()) {
          logger.trace("Failed to convert bean '" + name + "' to required type '" +
              ClassUtils.getQualifiedName(requiredType) + "'", ex);
        }
        throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
      }
    }
    return (T) bean;
  }