Spring bean生命周期[4] - createBean[2]

325 阅读5分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

第三步:AbstractAutowireCapableBeanFactory.createBean

回顾一下:

  • 到了这里,mbd中的beanClass对象还是一个String,并不能支持直接构造一个对象。

因此接下来首先需要去找到对应类。

查找类
 Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
 if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    mbdToUse = new RootBeanDefinition(mbd);
    mbdToUse.setBeanClass(resolvedClass);
 }
 ​
     protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
             throws CannotLoadBeanClassException {
 ​
         try {
             //这里其实并不是指有没有beanClass对象,而是beanClass对象是不是class类型的
             if (mbd.hasBeanClass()) {
                 return mbd.getBeanClass();
             }
             if (System.getSecurityManager() != null) {
                 return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
                         () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
             }
             else {
                 return doResolveBeanClass(mbd, typesToMatch);
             }
         }
         catch (PrivilegedActionException pae) {
             ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
             throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
         }
         catch (ClassNotFoundException ex) {
             throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
         }
         catch (LinkageError err) {
             throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
         }
     }

根据上面的流程这里就会调用这个方法:

 @Nullable
 private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
       throws ClassNotFoundException {
     //获取类加载器
     //这里可能是默认的,也可能在之前被显式set的
    ClassLoader beanClassLoader = getBeanClassLoader();
    ClassLoader dynamicLoader = beanClassLoader;
    boolean freshResolve = false;
 ​
    if (!ObjectUtils.isEmpty(typesToMatch)) {
       // When just doing type checks (i.e. not creating an actual instance yet),
       // use the specified temporary class loader (e.g. in a weaving scenario).
       ClassLoader tempClassLoader = getTempClassLoader();
       if (tempClassLoader != null) {
          dynamicLoader = tempClassLoader;
          freshResolve = true;
          if (tempClassLoader instanceof DecoratingClassLoader) {
             DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
             for (Class<?> typeToMatch : typesToMatch) {
                dcl.excludeClass(typeToMatch.getName());
             }
          }
       }
    }
 ​
     //获取类名
    String className = mbd.getBeanClassName();
    if (className != null) {
        //解析Spring表达式SPEL,可以替代class的名称
       Object evaluated = evaluateBeanDefinitionString(className, mbd);
       if (!className.equals(evaluated)) {
          // A dynamically resolved expression, supported as of 4.2...
          if (evaluated instanceof Class) {
             return (Class<?>) evaluated;
          }
          else if (evaluated instanceof String) {
             className = (String) evaluated;
             freshResolve = true;
          }
          else {
             throw new IllegalStateException("Invalid class name expression result: " + evaluated);
          }
       }
        //类加载器加载
       if (freshResolve) {
          // When resolving against a temporary class loader, exit early in order
          // to avoid storing the resolved Class in the bean definition.
          if (dynamicLoader != null) {
             try {
                return dynamicLoader.loadClass(className);
             }
             catch (ClassNotFoundException ex) {
                if (logger.isTraceEnabled()) {
                   logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
                }
             }
          }
          return ClassUtils.forName(className, dynamicLoader);
       }
    }
 ​
    // Resolve regularly, caching the result in the BeanDefinition...
    return mbd.resolveBeanClass(beanClassLoader);
 }
  • getBeanClassLoader():

    这里获取的,其实是 先获取Thread.currentThread().getContextClassLoader(),获取不到就是ClassUtils.class.getClassLoader(),再获取不到就是ClassLoader.getSystemClassLoader()了。

随后如果拿到了,就会赋值:

 mbdToUse = new RootBeanDefinition(mbd);
 mbdToUse.setBeanClass(resolvedClass);
重写方法

@todo后面补充,和@Lookup注解有关

 try {
    mbdToUse.prepareMethodOverrides();
 }
 catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
          beanName, "Validation of method overrides failed", ex);
 }
尝试让beanPostProcessor替我们做创建工作

走了前面的步骤,此时拿到了beanClass名称了,此时要做一下前置处理。

看注解这里是看在初始化前有没有beanPostProcessor能把bean代理一下,如果有这个冤大头,那么下面就不走了,直接返回:

 try {
    // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
        //看这里,如果获得了bean就直接返回了
       return bean;
    }
 }
 catch (Throwable ex) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
          "BeanPostProcessor before instantiation of bean failed", ex);
 }
 ​
 ​
 ​
 //这里就能看出来是个啥了,下面的两个apply就是循环beanPostProcessor了
     protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
         Object bean = null;
         if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
             // Make sure bean class is actually resolved at this point.
             //hasInstantiationAwareBeanPostProcessors():
             //这一步会判断是否有InstantiationAwareBeanPostProcessor的缓存,这里会在启动时先初始化BeanPostProcessorCache,如果没有调用也没关系,这里调用的时候也会来一个初始化
             if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                 Class<?> targetType = determineTargetType(beanName, mbd);
                 if (targetType != null) {
                     //初始化前处理,如果有一个确实要处理了而且创建成功了,就不会让后面的来处理了
 //注意一下这里名称等校验需要自己来,并不会对class对强制校验,这个地方是为了代理对象的方便,如果返回的和指定的class无关,会在后面处理的时候出问题
                     //这里有一个比较关键的postProcessor就是AOP的代理,后面注意一下
                     bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                     if (bean != null) {
                         //初始化之后处理,这里和上面不一样,如果处理了并返回的不是null就会继续处理,如果返回了null,那就返回null
                         bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                     }
                 }
             }
             //标记一下前置处理搞定了没
             mbd.beforeInstantiationResolved = (bean != null);
         }
         return bean;
     }
创建bean

如果上一步没有合适的BeanPostProcessor,那么只能自己创建了:

     try {
       Object beanInstance = doCreateBean(beanName, mbdToUse, args);
       if (logger.isTraceEnabled()) {
          logger.trace("Finished creating instance of bean '" + beanName + "'");
       }
       return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
       // A previously detected exception with proper bean creation context already,
       // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
       throw ex;
    }
    catch (Throwable ex) {
       throw new BeanCreationException(
             mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
 }

这里就是另外一个doCreateBean了,需要知道在Spring里,XXX一般会做一些额外处理,而doXXX就是最基础的XXX了,本地干活:

 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
       throws BeanCreationException {
 ​
    // Instantiate the bean.
     //推断构造方法相关
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        //有可能在Spring启动过程中就需要提前生成一些factoryBean,因此这里会处理一下
       instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //这里就会推断一下构造方法:有@Bean就走@Bean,没有就推断构造方法实例化
       instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
     //这里就从上面的beanWrapper拿到bean了
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
       mbd.resolvedTargetType = beanType;
    }
 ​
    // Allow post-processors to modify the merged bean definition.
     //这里会让postProcessor来尝试处理一下BeanDefinition,这里是实例化后,属性填充前的
     //这里可以往BD里填一些属性项,让后续步骤中部分的属性填充,强制从这里填充的属性项里取
     //比如这里有个@Autowired
    synchronized (mbd.postProcessingLock) {
       if (!mbd.postProcessed) {
          try {
             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.
     //这里和循环依赖相关,暂且不说
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
          isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
       if (logger.isTraceEnabled()) {
          logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
       }
       addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
 ​
    // Initialize the bean instance.
     //这里就是属性填充了
    Object exposedObject = bean;
    try {
       populateBean(beanName, mbd, instanceWrapper);
       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) {
       Object earlySingletonReference = getSingleton(beanName, false);
       if (earlySingletonReference != null) {
          if (exposedObject == bean) {
             exposedObject = earlySingletonReference;
          }
          else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
             String[] dependentBeans = getDependentBeans(beanName);
             Set<String> actualDependentBeans = new LinkedHashSet<>(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;
 }
  • populateBean:属性填充。

     protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
           if (mbd.hasPropertyValues()) {
              throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
           }
           else {
              // Skip property population phase for null instance.
              return;
           }
        }
     ​
        // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
        // state of the bean before properties are set. This can be used, for example,
        // to support styles of field injection.
         //beanPostProcessor来处理依赖注入
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
           for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
              if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                 return;
              }
           }
        }
     ​
         //这里是Spring自带的autowired
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
     ​
        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
           MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
           // Add property values based on autowire by name if applicable.
           if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
              autowireByName(beanName, mbd, bw, newPvs);
           }
           // Add property values based on autowire by type if applicable.
           if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
              autowireByType(beanName, mbd, bw, newPvs);
           }
           pvs = newPvs;
        }
     ​
         //这里同样使用beanPostProcessor,@Autowired,@Resource都是在这里进行的
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
     ​
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
           if (pvs == null) {
              pvs = mbd.getPropertyValues();
           }
           for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
              PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
              if (pvsToUse == null) {
                 if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                 }
                 pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                 if (pvsToUse == null) {
                    return;
                 }
              }
              pvs = pvsToUse;
           }
        }
        if (needsDepCheck) {
           if (filteredPds == null) {
              filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
           }
           checkDependencies(beanName, mbd, filteredPds, pvs);
        }
     ​
        if (pvs != null) {
           applyPropertyValues(beanName, mbd, bw, pvs);
        }
     }
    
  • 自带的autowired:
 int resolvedAutowireMode = mbd.getResolvedAutowireMode();
 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    // Add property values based on autowire by name if applicable.
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
       autowireByName(beanName, mbd, bw, newPvs);
    }
    // Add property values based on autowire by type if applicable.
    if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
       autowireByType(beanName, mbd, bw, newPvs);
    }
    pvs = newPvs;
 }

如果没有@Autowired的属性如何处理?

  • 这里需要在某个地方对需要注入的bean,标注@Bean(autowired = Autowired.BY_TYPE)(或者byName))的注解并按照@Bean的方式声明bean,而且没有标注@Autowired的变量需要给出对应的set方法,这样子就可以注入。

    不过该方式已标注为deprecated