spring源碼解析bean初始化與依賴注入二

前言java

本文轉自「天河聊技術」微信公衆號spring

本次接着上次的介紹來解析bean初始化和依賴注入數組

 

正文微信

上一次跟蹤到這個方法app

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBeanless

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable 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.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.容許後處理器修改合併後的bean定義。
   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.isDebugEnabled()) {
         logger.debug("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 " +
                     "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
            }
         }
      }
   }

   // Register bean as disposable.bean註冊爲一次性。
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}

找到這行代碼ide

//        建立bean對象
         instanceWrapper = createBeanInstance(beanName, mbd, args);

進入到這個方法函數

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstancepost

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
      // Make sure bean class is actually resolved at this point.
      Class<?> beanClass = resolveBeanClass(mbd, beanName);

//    類必須是public,構造方法必須是public
      if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
      }

      Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
      if (instanceSupplier != null) {
         return obtainFromSupplier(instanceSupplier, beanName);
      }

//    若是工廠方法不爲空,就用工廠方法建立bean
      if (mbd.getFactoryMethodName() != null)  {
         return instantiateUsingFactoryMethod(beanName, mbd, args);
      }

      // Shortcut when re-creating the same bean...
      boolean resolved = false;
      boolean autowireNecessary = false;
      if (args == null) {
         synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
               resolved = true;
               autowireNecessary = mbd.constructorArgumentsResolved;
            }
         }
      }
      if (resolved) {
         if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
         }
         else {
            return instantiateBean(beanName, mbd);
         }
      }

      // Need to determine the constructor...
      Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
      if (ctors != null ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
//       構造參數注入
         return autowireConstructor(beanName, mbd, ctors, args);
      }

      // No special handling: simply use no-arg constructor.無需特殊處理:只需使用無arg構造函數。
      return instantiateBean(beanName, mbd);
   }

找到這一行代碼ui

//     若是工廠方法不爲空,就用工廠方法建立bean
      if (mbd.getFactoryMethodName() != null)  {
         return instantiateUsingFactoryMethod(beanName, mbd, args);
      }

優先使用工廠方法建立bean對象

 

進入這個方法

org.springframework.beans.factory.support.ConstructorResolver#instantiateUsingFactoryMethod

這一行代碼

//        默認類型自動裝配,判斷是不是構造參數裝配
         boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);

找到這一行代碼

beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
      mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);

執行工廠方法建立對象

 

返回到這個方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance這一行代碼

   構造方法注入
            return autowireConstructor(beanName, mbd, null, null);

進入這個方法

org.springframework.beans.factory.support.ConstructorResolver#autowireConstructor

public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
         @Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {

      BeanWrapperImpl bw = new BeanWrapperImpl();
      this.beanFactory.initBeanWrapper(bw);

      Constructor<?> constructorToUse = null;
      ArgumentsHolder argsHolderToUse = null;
      Object[] argsToUse = null;

      if (explicitArgs != null) {
         argsToUse = explicitArgs;
      }
      else {
         Object[] argsToResolve = null;
         synchronized (mbd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
               // Found a cached constructor...
               argsToUse = mbd.resolvedConstructorArguments;
               if (argsToUse == null) {
                  argsToResolve = mbd.preparedConstructorArguments;
               }
            }
         }
         if (argsToResolve != null) {
//          解析bean定義中的方法
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
         }
      }

      if (constructorToUse == null) {
         // Need to resolve the constructor.判斷是不是構造參數注入
         boolean autowiring = (chosenCtors != null ||
               mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
         ConstructorArgumentValues resolvedValues = null;

         int minNrOfArgs;
         if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
         }
         else {
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            resolvedValues = new ConstructorArgumentValues();
//          解析構造參數
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
         }

         // Take specified constructors, if any.使用指定的構造函數(若是有的話)。
         Constructor<?>[] candidates = chosenCtors;
         if (candidates == null) {
            Class<?> beanClass = mbd.getBeanClass();
            try {
               candidates = (mbd.isNonPublicAccessAllowed() ?
                     beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }
            catch (Throwable ex) {
               throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                     "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                     "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
            }
         }
         AutowireUtils.sortConstructors(candidates);
         int minTypeDiffWeight = Integer.MAX_VALUE;
         Set<Constructor<?>> ambiguousConstructors = null;
         LinkedList<UnsatisfiedDependencyException> causes = null;

         for (Constructor<?> candidate : candidates) {
            Class<?>[] paramTypes = candidate.getParameterTypes();

            if (constructorToUse != null && argsToUse.length > paramTypes.length) {
               // Already found greedy constructor that can be satisfied ->
               // do not look any further, there are only less greedy constructors left.
               break;
            }
            if (paramTypes.length < minNrOfArgs) {
               continue;
            }

            ArgumentsHolder argsHolder;
            if (resolvedValues != null) {
               try {
//                @ConstructorProperties註釋解析
                  String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
                  if (paramNames == null) {
                     ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                     if (pnd != null) {
                        paramNames = pnd.getParameterNames(candidate);
                     }
                  }
//                解析構造參數並轉換成數組
                  argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                        getUserDeclaredConstructor(candidate), autowiring);
               }
               catch (UnsatisfiedDependencyException ex) {
                  if (this.beanFactory.logger.isTraceEnabled()) {
                     this.beanFactory.logger.trace(
                           "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                  }
                  // Swallow and try next constructor.
                  if (causes == null) {
                     causes = new LinkedList<>();
                  }
                  causes.add(ex);
                  continue;
               }
            }
            else {
               // Explicit arguments given -> arguments length must match exactly.
               if (paramTypes.length != explicitArgs.length) {
                  continue;
               }
               argsHolder = new ArgumentsHolder(explicitArgs);
            }

            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                  argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // Choose this constructor if it represents the closest match.
            if (typeDiffWeight < minTypeDiffWeight) {
               constructorToUse = candidate;
               argsHolderToUse = argsHolder;
               argsToUse = argsHolder.arguments;
               minTypeDiffWeight = typeDiffWeight;
               ambiguousConstructors = null;
            }
            else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
               if (ambiguousConstructors == null) {
                  ambiguousConstructors = new LinkedHashSet<>();
                  ambiguousConstructors.add(constructorToUse);
               }
               ambiguousConstructors.add(candidate);
            }
         }

         if (constructorToUse == null) {
            if (causes != null) {
               UnsatisfiedDependencyException ex = causes.removeLast();
               for (Exception cause : causes) {
                  this.beanFactory.onSuppressedException(cause);
               }
               throw ex;
            }
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Could not resolve matching constructor " +
                  "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
         }
         else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Ambiguous constructor matches found in bean '" + beanName + "' " +
                  "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                  ambiguousConstructors);
         }

         if (explicitArgs == null) {
            argsHolderToUse.storeCache(mbd, constructorToUse);
         }
      }

      try {
//       bean初始化策略,若是容器中bean方法須要被覆蓋,採用cglib建立子類
         final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
         Object beanInstance;

         if (System.getSecurityManager() != null) {
            final Constructor<?> ctorToUse = constructorToUse;
            final Object[] argumentsToUse = argsToUse;
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
//                初始化bean
                  strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
                  beanFactory.getAccessControlContext());
         }
         else {
            beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
         }

         bw.setBeanInstance(beanInstance);
         return bw;
      }
      catch (Throwable ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Bean instantiation via constructor failed", ex);
      }
   }

返回到這個方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance

使用默認構造參數初始化bean
            return instantiateBean(beanName, mbd);

進入這個方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#instantiateBean

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
      try {
         Object beanInstance;
         final BeanFactory parent = this;
         if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
//                獲取bean初始化策略並進行初始化
                  getInstantiationStrategy().instantiate(mbd, beanName, parent),
                  getAccessControlContext());
         }
         else {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
         }
         BeanWrapper bw = new BeanWrapperImpl(beanInstance);
         initBeanWrapper(bw);
         return bw;
      }
      catch (Throwable ex) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
      }
   }
   獲取bean初始化策略並進行初始化
                  getInstantiationStrategy().instantiate(mbd, beanName, parent),

進入這個方法

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate(org.springframework.beans.factory.support.RootBeanDefinition, java.lang.String, org.springframework.beans.factory.BeanFactory)

@Override
   public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
      // Don't override the class with CGLIB if no overrides.若是沒有重寫,不要使用CGLIB覆蓋該類。
      if (!bd.hasMethodOverrides()) {
         Constructor<?> constructorToUse;
         synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
               final Class<?> clazz = bd.getBeanClass();
               if (clazz.isInterface()) {
                  throw new BeanInstantiationException(clazz, "Specified class is an interface");
               }
               try {
                  if (System.getSecurityManager() != null) {
                     constructorToUse = AccessController.doPrivileged(
                           (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                  }
                  else {
                     constructorToUse = clazz.getDeclaredConstructor();
                  }
                  bd.resolvedConstructorOrFactoryMethod = constructorToUse;
               }
               catch (Throwable ex) {
                  throw new BeanInstantiationException(clazz, "No default constructor found", ex);
               }
            }
         }
//       使用構造方法建立類
         return BeanUtils.instantiateClass(constructorToUse);
      }
      else {
         // Must generate CGLIB subclass.必須生成CGLIB子類
         return instantiateWithMethodInjection(bd, beanName, owner);
      }
   }

返回到這個方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean這一行代碼

//        填充依賴注入的bean對象
         populateBean(beanName, mbd, instanceWrapper);

進入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#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.
      boolean continueWithPropertyPopulation = true;

      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                  continueWithPropertyPopulation = false;
                  break;
               }
            }
         }
      }

      if (!continueWithPropertyPopulation) {
         return;
      }

      PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

//    若是是按名稱注入或者按類型注入
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

         // Add property values based on autowire by name if applicable.若是能夠的話,在autowire的基礎上添加屬性值。
         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
//          按名稱注入
            autowireByName(beanName, mbd, bw, newPvs);
         }

         // Add property values based on autowire by type if applicable.若是能夠的話,按類型添加基於autowire的屬性值。
         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
//          按類型注入
            autowireByType(beanName, mbd, bw, newPvs);
         }

         pvs = newPvs;
      }

      boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
      boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

      if (hasInstAwareBpps || needsDepCheck) {
         if (pvs == null) {
            pvs = mbd.getPropertyValues();
         }
         PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
         if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
               if (bp instanceof InstantiationAwareBeanPostProcessor) {
                  InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                  pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                  if (pvs == null) {
                     return;
                  }
               }
            }
         }
         if (needsDepCheck) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
         }
      }

      if (pvs != null) {
         applyPropertyValues(beanName, mbd, bw, pvs);
      }
   }

找到這行代碼

//           按類型注入
            autowireByType(beanName, mbd, bw, newPvs);

進入這個方法org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowireByType

protected void autowireByType(
         String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

      TypeConverter converter = getCustomTypeConverter();
      if (converter == null) {
         converter = bw;
      }

      Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
      String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
      for (String propertyName : propertyNames) {
         try {
            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
            // Don't try autowiring by type for type Object: never makes sense,
            // even if it technically is a unsatisfied, non-simple property.
            if (Object.class != pd.getPropertyType()) {
               MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
               // Do not allow eager init for type matching in case of a prioritized post-processor.
               boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
               DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//             解析依賴值
               Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
               if (autowiredArgument != null) {
                  pvs.add(propertyName, autowiredArgument);
               }
               for (String autowiredBeanName : autowiredBeanNames) {
                  registerDependentBean(autowiredBeanName, beanName);
                  if (logger.isDebugEnabled()) {
                     logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
                           propertyName + "' to bean named '" + autowiredBeanName + "'");
                  }
               }
               autowiredBeanNames.clear();
            }
         }
         catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
         }
      }
   }

找到這行代碼

   解析依賴值
               Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);

進入這個方法

org.springframework.beans.factory.support.DefaultListableBeanFactory#createOptionalDependency

private Optional<?> createOptionalDependency(
         DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {

      DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
         @Override
         public boolean isRequired() {
            return false;
         }
         @Override
         public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
            return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
                  super.resolveCandidate(beanName, requiredType, beanFactory));
         }
      };
//    解析依賴
      return Optional.ofNullable(doResolveDependency(descriptorToUse, beanName, null, null));
   }

本次介紹到這裏,下次繼續。

最後

 

本次介紹到這裏,以上內容僅供參考。