Spring源码:工厂方法实例化Bean

源代码

该函数在类ConstructorResolver(该类的作用:构造函数和工厂方法解析的代理,主要作用通过参数匹配执行构造函数解析)为了简化分析,去除了不必要的异常和日志。

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

  BeanWrapperImpl bw = new BeanWrapperImpl();
  // 把BeanFactory的框架内置和自定义PropertyEditor放到BeanWrapperImpl中
  this.beanFactory.initBeanWrapper(bw);

  Object factoryBean;
  Class<?> factoryClass;
  boolean isStatic;

  // 第一部分:获取工厂类class、工厂类方法、参数
  String factoryBeanName = mbd.getFactoryBeanName();
  if (factoryBeanName != null) {
    // 加载标签factory-bean指向的class,一般说含有factory-bean标签时,其指向的class是非静态
    factoryBean = this.beanFactory.getBean(factoryBeanName);
    factoryClass = factoryBean.getClass();
    isStatic = false;
  } else {
      // 不含有factory-bean标签,工厂Bean含有创建Bean的静态方法
      factoryBean = null;
      factoryClass = mbd.getBeanClass();
      isStatic = true;
  }
    Method factoryMethodToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    // 若getBean方法调用时指定了方法参数,则直接使用
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        // 若getBean方法调用时没有指定方法参数,则尝试从配置文件中加载
        Object[] argsToResolve = null;
        // 对mbd的构造函数加锁
        synchronized (mbd.constructorArgumentLock) {
            // 从缓存中取构造函数或工厂方法
            factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
            // 若取到构造函数或工厂方法,且构造函数的所有参数已解析
            if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
                // 从缓存中取解析的参数
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    // 若从缓存中没有取到解析的参数,就取配置文件中的参数
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        if (argsToResolve != null) {
            // 解析配置文件中的参数类型,如参数类型转换
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
        }
    }

    // 第二部分:
    // 若没有被缓存的构造函数或工厂方法,且参数也无法获取,重新分析
    if (factoryMethodToUse == null || argsToUse == null) {
        factoryClass = ClassUtils.getUserClass(factoryClass);
        // 根据mdb的nonPublicAccessAllowed字段获取候选的方法集合rawCandidates
        Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
        // 对 rawCandidates 集合进一步筛选与工厂方法名相同的的方法集合candidateSet
        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()]);
        /**
        ** 对给定的工厂方法进行排序
        ** 先公共方法,再对公共方法参数递减排序
        ** 再私有方法,再对私有方法参数递减排序
        **/
        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 {
            // 提取配置文件中的配置的构造函数参数
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            // 用于承载解析后的构造函数参数的值
            resolvedValues = new ConstructorArgumentValues();
            // 能解析到的参数个数(参考分析2)
            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.
                    String[] paramNames = null;
                    // 获取参数名称解析器
                    ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                    if (pnd != null) {
                        // 解析candidate方法中的参数
                        paramNames = pnd.getParameterNames(candidate);
                    }
                    // 给定已解析的构造函数参数值,创建一个参数数组来调用构造函数或工厂方法
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
                } 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 factory method if it represents the closest match.
                if (typeDiffWeight < minTypeDiffWeight) {
                    factoryMethodToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousFactoryMethods = null;
                } 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);
                }
            }
        } //for (Method candidate : candidates) 

        if (factoryMethodToUse == null) {
            // 抛出异常,没有找到对应的工厂方法
        } else if (void.class == factoryMethodToUse.getReturnType()) {
            // 抛出异常,需要返回值
        } else if (ambiguousFactoryMethods != null) {
            // 抛出异常,模糊的工厂方法与bean中匹配了
        }

        if (explicitArgs == null && argsHolderToUse != null) {
            argsHolderToUse.storeCache(mbd, factoryMethodToUse);
        }
    }

    //
    Object beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
    if (beanInstance == null) {
        return null;
    }
    bw.setBeanInstance(beanInstance);
    return bw;
}

分析:

  1. RootBeanDefinition的几个属性

    //缓存已解析的构造函数或工厂方法
    Object resolvedConstructorOrFactoryMethod;
    
    // 将构造函数参数标记为是否已解析
    boolean constructorArgumentsResolved = false;
    
    // 缓存完全解析的构造函数参数
    Object[] resolvedConstructorArguments;
    
    // 缓存部分准备好的构造函数参数,即配置文件中配置的参数
    Object[] preparedConstructorArguments;
  2. 解析配置文件中的参数函数resolveConstructorArguments,该函数在类ConstructorResolver中,

    private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
      // 获取类型转换器
      TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
      TypeConverter converter = (customConverter != null ? customConverter : bw);
      BeanDefinitionValueResolver valueResolver =
            new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
    
       // 配置文件中参数的个数
      int minNrOfArgs = cargs.getArgumentCount();
    
      for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
          // TODO
          int index = entry.getKey();
          if (index > minNrOfArgs) {
              minNrOfArgs = index + 1;
          }
          ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
          if (valueHolder.isConverted()) {
              // 若已经转换过
              resolvedValues.addIndexedArgumentValue(index, valueHolder);
          } else {
              // 没有转换过
              // BeanDefinitionValueResolver类resolveValueIfNecessary方法,主要解析Array,Set,Map,props和字符串类型的间接引用
              Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
              ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
              resolvedValueHolder.setSource(valueHolder);
              resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
          }
      }
    
      for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
          if (valueHolder.isConverted()) {
              resolvedValues.addGenericArgumentValue(valueHolder);
          } else {
              Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
              ConstructorArgumentValues.ValueHolder resolvedValueHolder =
                  new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
              resolvedValueHolder.setSource(valueHolder);
              resolvedValues.addGenericArgumentValue(resolvedValueHolder);
          }
      }
       return minNrOfArgs;
    }
  3. 实例化Bean,该方法在SimpleInstantiationStrategy类中,通过反射调用

    public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, Object factoryBean, final Method factoryMethod, Object... args) {
       ReflectionUtils.makeAccessible(factoryMethod);
       Method priorInvokedFactoryMethod = currentlyInvokedFactoryMethod.get();
       try {
           currentlyInvokedFactoryMethod.set(factoryMethod);
           return factoryMethod.invoke(factoryBean, args);
       } finally {
           if (priorInvokedFactoryMethod != null) {
               currentlyInvokedFactoryMethod.set(priorInvokedFactoryMethod);
           } else {
               currentlyInvokedFactoryMethod.remove();
           }
       } // finally
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值