Spring源码阅读(七)通过FactoryMethod创建对象

直接上源码

public BeanWrapper instantiateUsingFactoryMethod(
      final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {

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

   Object factoryBean;
   Class<?> factoryClass;
   boolean isStatic;
   // 获取FactoryBean名称
   String factoryBeanName = mbd.getFactoryBeanName();
   // 如果FactoryBean名称不等于null
   if (factoryBeanName != null) {
      if (factoryBeanName.equals(beanName)) {
         throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
               "factory-bean reference points back to the same bean definition");
      }
      // 从beanFactory中获取FactoryBean的对象
      factoryBean = this.beanFactory.getBean(factoryBeanName);
      if (factoryBean == null) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "factory-bean '" + factoryBeanName + "' (or a BeanPostProcessor involved) returned null");
      }
      if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
         throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared " +
               "through the creation of the factory bean that its bean definition points to");
      }
      // 获取FactoryBean对象的Class对象
      factoryClass = factoryBean.getClass();
      isStatic = false;
   }
   // 如果是静态工厂方法
   else {
      // It's a static factory method on the bean class.
      if (!mbd.hasBeanClass()) {
         throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
               "bean definition declares neither a bean class nor a factory-bean reference");
      }
      // 静态工厂方法,不需要创建对象来调用方法,所以为null
      factoryBean = null;
      // 获取FactoryBean对象的Class对象
      factoryClass = mbd.getBeanClass();
      // 标志为静态的
      isStatic = true;
   }

   Method factoryMethodToUse = null;
   ArgumentsHolder argsHolderToUse = null;
   Object[] argsToUse = null;

   // 如果是通过编程的方式(如getBean中传递的参数)传过来的参数,则直接使用
   if (explicitArgs != null) {
      argsToUse = explicitArgs;
   }
   else {
      Object[] argsToResolve = null;
      synchronized (mbd.constructorArgumentLock) {
         // 从缓存中获取FactoryMethod
         factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod
         // 如果可以获取到FactoryMethod并且FactoryMethod的参数已经解析过了
         if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
            // Found a cached factory method...
            // 从缓存中获取FactoryMethod的参数
            argsToUse = mbd.resolvedConstructorArguments;
            if (argsToUse == null) {
               argsToResolve = mbd.preparedConstructorArguments;
            }
         }
      }
      if (argsToResolve != null) {
         // 解析参数值,进行类型转化
         argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
      }
   }
   // 如果是第一次实例化,此时的FactoryMethod和参数为null
   if (factoryMethodToUse == null || argsToUse == null) {
      // Need to determine the factory method...
      // Try all methods with this name to see if they match the given arguments.
      factoryClass = ClassUtils.getUserClass(factoryClass);
	  // 获取所有FactoryClass中所有的方法
      Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
      List<Method> candidateSet = new ArrayList<Method>();
      // 遍历所有的方法
      for (Method candidate : rawCandidates) {
         // 方法是静态的并且是工厂方法,则加入到候选方法中
         if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
            candidateSet.add(candidate);
         }
      }
      Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);
      // 对候选方法进行排序,public方法优先,其次按照参数个数降序排列
      AutowireUtils.sortFactoryMethods(candidates);

      ConstructorArgumentValues resolvedValues = null;
      boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
      int minTypeDiffWeight = Integer.MAX_VALUE;
      Set<Method> ambiguousFactoryMethods = null;

      int minNrOfArgs;
      if (explicitArgs != null) {
         minNrOfArgs = explicitArgs.length;
      }
      else {
         // We don't have arguments passed in programmatically, so we need to resolve the
         // arguments specified in the constructor arguments held in the bean definition.
         ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
         resolvedValues = new ConstructorArgumentValues();
         // 解析构造参数值,并且返回个数
         minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
      }

      LinkedList<UnsatisfiedDependencyException> causes = null;
	  // 遍历候选的方法
      for (Method candidate : candidates) {
         // 获取候选方法的参数类型
         Class<?>[] paramTypes = candidate.getParameterTypes();
		 // 如果候选方法形参的个数大于等于指定的实参个数
         if (paramTypes.length >= minNrOfArgs) {
            ArgumentsHolder argsHolder;

            if (resolvedValues != null) {
               // Resolved constructor arguments: type conversion and/or autowiring necessary.
               try {
                  String[] paramNames = null;
                  ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                  if (pnd != null) {
                     paramNames = pnd.getParameterNames(candidate);
                  }
                  // 将实参转化为和形参一样的类型
                  argsHolder = createArgumentArray(
                        beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
               }
               catch (UnsatisfiedDependencyException ex) {
                  if (this.beanFactory.logger.isTraceEnabled()) {
                     this.beanFactory.logger.trace("Ignoring factory method [" + candidate +
                           "] of bean '" + beanName + "': " + ex);
                  }
                  // Swallow and try next overloaded factory method.
                  if (causes == null) {
                     causes = new LinkedList<UnsatisfiedDependencyException>();
                  }
                  causes.add(ex);
                  continue;
               }
            }

            else {
               // Explicit arguments given -> arguments length must match exactly.
               // 如果是编程指定的参数(如:getBean的方式),则实参个数必须与形参个数相同
               if (paramTypes.length != explicitArgs.length) {
                  continue;
               }
               argsHolder = new ArgumentsHolder(explicitArgs);
            }
			// 计算候选方法的权重
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                  argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // Choose this factory method if it represents the closest match.
            if (typeDiffWeight < minTypeDiffWeight) {
               factoryMethodToUse = candidate;
               argsHolderToUse = argsHolder;
               argsToUse = argsHolder.arguments;
               minTypeDiffWeight = typeDiffWeight;
               ambiguousFactoryMethods = null;
            }
            // Find out about ambiguity: In case of the same type difference weight
            // for methods with the same number of parameters, collect such candidates
            // and eventually raise an ambiguity exception.
            // However, only perform that check in non-lenient constructor resolution mode,
            // and explicitly ignore overridden methods (with the same parameter signature).
            else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
                  !mbd.isLenientConstructorResolution() &&
                  paramTypes.length == factoryMethodToUse.getParameterTypes().length &&
                  !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
               if (ambiguousFactoryMethods == null) {
                  ambiguousFactoryMethods = new LinkedHashSet<Method>();
                  ambiguousFactoryMethods.add(factoryMethodToUse);
               }
               ambiguousFactoryMethods.add(candidate);
            }
         }
      }

      if (factoryMethodToUse == null) {
         if (causes != null) {
            UnsatisfiedDependencyException ex = causes.removeLast();
            for (Exception cause : causes) {
               this.beanFactory.onSuppressedException(cause);
            }
            throw ex;
         }
         List<String> argTypes = new ArrayList<String>(minNrOfArgs);
         if (explicitArgs != null) {
            for (Object arg : explicitArgs) {
               argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
            }
         }
         else {
            Set<ValueHolder> valueHolders = new LinkedHashSet<ValueHolder>(resolvedValues.getArgumentCount());
            valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
            valueHolders.addAll(resolvedValues.getGenericArgumentValues());
            for (ValueHolder value : valueHolders) {
               String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
                     (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
               argTypes.add(argType);
            }
         }
         String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "No matching factory method found: " +
               (mbd.getFactoryBeanName() != null ?
                  "factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
               "factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
               "Check that a method with the specified name " +
               (minNrOfArgs > 0 ? "and arguments " : "") +
               "exists and that it is " +
               (isStatic ? "static" : "non-static") + ".");
      }
      else if (void.class == factoryMethodToUse.getReturnType()) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Invalid factory method '" + mbd.getFactoryMethodName() +
               "': needs to have a non-void return type!");
      }
      else if (ambiguousFactoryMethods != null) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Ambiguous factory method matches found in bean '" + beanName + "' " +
               "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
               ambiguousFactoryMethods);
      }
	  // 如果是第一次创建,则保存到缓存中
      if (explicitArgs == null && argsHolderToUse != null) {
         argsHolderToUse.storeCache(mbd, factoryMethodToUse);
      }
   }

   try {
      Object beanInstance;

      if (System.getSecurityManager() != null) {
         final Object fb = factoryBean;
         final Method factoryMethod = factoryMethodToUse;
         final Object[] args = argsToUse;
         beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
               return beanFactory.getInstantiationStrategy().instantiate(
                     mbd, beanName, beanFactory, fb, factoryMethod, args);
            }
         }, beanFactory.getAccessControlContext());
      }
      else {
         // 实例化
         beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
               mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
      }

      if (beanInstance == null) {
         return null;
      }
      // 设置到BeanWrapper中
      bw.setBeanInstance(beanInstance);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean instantiation via factory method failed", ex);
   }
}

总结

  1. 工厂方法分为静态工厂和实例工厂。如果是静态工厂,则工厂类为beanClass,如果是实例工厂,则工厂类为FactoryBean对应的class。

  2. 同时匹配的工厂方法可能有多个,需要选出最合适的。

  3. 使用工厂方法进行实例化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值