spring源码解析(四) 推断构造方法

该篇以createBeanInstance方法为起点分析推断构造方法

怎么一步步到createBeanInstance方法

refresh()-》finishBeanFactoryInitialization-》preInstantiateSingletons-》getBean-》 doGetBean-》createBean-》doCreateBean-》createBeanInstance

推断构造方法源码

推断构造方法是在创建实例化时进行推断的,也就是这个createBeanInstance方法。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // 创建一个bean实例(返回一个原始对象)

   // Make sure bean class is actually resolved at this point.
   // 1. 得到bean的class,并验证class的访问权限是不是public
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

   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());
   }

   // 2. 这是Spring提供给开发者的扩展点
   // 如果我们要自己来实现创建对象的过程, 那么就可以提供一个Supplier的实现类,
   // 当一个BeanDefinition中存在一个Supplier实现类的时候, Spring就利用这个类的get方法来获取实例,
   // 而不再走Spring创建对象的逻辑
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }

   // 3.通过factoryMethod实例化这个bean
   // factorMethod这个名称在xml中还是比较常见的, 即通过工厂方法来创建bean对象
   // 如果是由@Bean注解创建的bean, 那么该对象就会走instantiateUsingFactoryMethod方法来创建的,而不会走下面的推断构造
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   boolean resolved = false;
   boolean autowireNecessary = false;
   // 如果在创建bean时没有手动指定构造方法的参数,那么则看当前BeanDefinition是不是已经确定了要使用的构造方法和构造方法参数
   // 注意:如果没有手动指定参数,那么就肯定是自动推断出来的,所以一旦发现当前BeanDefinition中已经确定了要使用的构造方法和构造方法参数,
   // 那么就要使用autowireConstructor()方法来构造一个bean对象
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         // 该BeanDefinition是否已经决定了要使用的构造方法或工厂方法
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            // 该BeanDefinition是否已经决定了要使用的构造方法参数
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) {
      // resolved为true,表示当前bean的构造方法已经确定出来了
      // autowireNecessary表示当前bean的构造方法的参数已经确定出来了
      if (autowireNecessary) {
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
         // 如果构造方法已经确定了,但是没有确定构造方法参数,那就表示没有构造方法参数,用无参的构造方法来实例化bean
         return instantiateBean(beanName, mbd);
      }
   }

   // 候选构造器
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

   // 通过BeanPostProcessor找出了构造方法
   // 或者BeanDefinition的autowire属性为AUTOWIRE_CONSTRUCTOR
   // 或者BeanDefinition中指定了构造方法参数值
   // 或者在getBean()时指定了args
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      // 进行构造方法推断并实例化
      return autowireConstructor(beanName, mbd, ctors, args);
   }
   // 没啥用
   ctors = mbd.getPreferredConstructors();
   if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
   }
   // 用无参的构造方法来实例化bean
   return instantiateBean(beanName, mbd);
}

再看57行这个方法determineConstructorsFromBeanPostProcessors,通过循环最终到了AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors方法

public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
      throws BeanCreationException {
   // 在实例化某个对象的过程中会调用这个方法,得到候选构造方法

   if (!this.lookupMethodsChecked.contains(beanName)) {
      if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
         try {
            Class<?> targetClass = beanClass;
            do {
               // 遍历当前beanClass中所有加了Lookup注解的方法,并且把这些方法的信息封装为LookupOverride对象加载mbd中
               ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                  Lookup lookup = method.getAnnotation(Lookup.class);
                  if (lookup != null) {
                     Assert.state(this.beanFactory != null, "No BeanFactory available");
                     LookupOverride override = new LookupOverride(method, lookup.value());
                     try {
                        RootBeanDefinition mbd = (RootBeanDefinition)
                              this.beanFactory.getMergedBeanDefinition(beanName);
                        mbd.getMethodOverrides().addOverride(override);
                     }
                     catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(beanName,
                              "Cannot apply @Lookup to beans without corresponding bean definition");
                     }
                  }
               });
               targetClass = targetClass.getSuperclass();
            }
            while (targetClass != null && targetClass != Object.class);

         }
         catch (IllegalStateException ex) {
            throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
         }
      }
      // lookupMethodsChecked是一个set,用来记录哪些bean的@lookup注解被解析了,下一次就不用解析了
      this.lookupMethodsChecked.add(beanName);
   }

   // 先检查candidateConstructorsCache中是否缓存了当前bean中可用的构造方法
   Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
   if (candidateConstructors == null) {
      // Fully synchronized resolution now...
      synchronized (this.candidateConstructorsCache) {
         candidateConstructors = this.candidateConstructorsCache.get(beanClass);

         // 如果没有筛选过构造方法,就开始筛选
         if (candidateConstructors == null) {
            Constructor<?>[] rawCandidates;
            try {
               // 拿到当前类所有的构造方法,如果没有写任何构造方法,这里会返回一个无参的构造方法
               rawCandidates = beanClass.getDeclaredConstructors();
            }
            catch (Throwable ex) {
               throw new BeanCreationException(beanName,
                     "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                     "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
            }

            // candidates 就是用来存储所有被筛选出来的构造方法,其实可以认为, 就是把所有@Autowired注解标注的方法放到里面,
            // 但是还多放了一个默认构造方法
            List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
            // requiredConstructor表示@Autowired标注并且required为true的构造方法, 因为只允许出现一个这样的构造方法, 
            //所以当这个变量存在值后, 又出现了一个相同情况的构造方法的话, Spring就会抛出一个错误
            Constructor<?> requiredConstructor = null;
            // defaultConstructor用来保存默认构造方法
            Constructor<?> defaultConstructor = null;

            // 如果是kotlin的类才起效,如果是java中的类则直接返回null
            Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
            int nonSyntheticConstructors = 0;

            // 遍历所有的构造方法
            for (Constructor<?> candidate : rawCandidates) {
               // nonSyntheticConstructors这个变量是和primaryConstructor != null一起使用的,所以也不用管
               if (!candidate.isSynthetic()) {
                  nonSyntheticConstructors++;
               }
               else if (primaryConstructor != null) {
                  continue;
               }

               // 查看该构造方法上是否存在@Autowired注解,或者看代理类的父类中对应的构造方法上是否存在@Autowired注解
               MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
               if (ann == null) {
                  // 如果当前类是cglib生成的代理类,则获取期父类
                  Class<?> userClass = ClassUtils.getUserClass(beanClass);
                  if (userClass != beanClass) {
                     try {
                        Constructor<?> superCtor =
                              userClass.getDeclaredConstructor(candidate.getParameterTypes());
                        ann = findAutowiredAnnotation(superCtor);
                     }
                     catch (NoSuchMethodException ex) {
                        // Simply proceed, no equivalent superclass constructor found...
                     }
                  }
               }

               // 如果构造方法上存在@Autowired注解
               if (ann != null) {
                  // requiredConstructor表示程序员手动指明的要使用的哪个构造方法
                  // 所以如果有多个构造方法上都写了@Autowired注解就会报错,required位true的情况下
                  // 因为作为程序员你如果告诉Spring多个构造方法,那Spring也就不知道到底要使用哪一个了
                  if (requiredConstructor != null) {
                     throw new BeanCreationException(beanName,
                           "Invalid autowire-marked constructor: " + candidate +
                           ". Found constructor with 'required' Autowired annotation already: " +
                           requiredConstructor);
                  }
                  // 查看@Autowired的required属性值,默认位true
                  boolean required = determineRequiredStatus(ann);
                  if (required) {
                     if (!candidates.isEmpty()) {
                        throw new BeanCreationException(beanName,
                              "Invalid autowire-marked constructors: " + candidates +
                              ". Found constructor with 'required' Autowired annotation: " +
                              candidate);
                     }
                     requiredConstructor = candidate;
                  }
                  // candidates中存的是加了@Autowired注解的构造方法
                  candidates.add(candidate);
               }
               // 如果当前构造方法上不存在@Autowired,并且是无参构造方法,则记录一下该无参构造方法
               // 所以我们可以方法,在遍历构造方法时,其实只关心无参构造方法和加了@Autowired注解的构造方法
               else if (candidate.getParameterCount() == 0) {
                  defaultConstructor = candidate;
               }
            }

            // 如果存在添加了@Autowired的构造方法
            if (!candidates.isEmpty()) {
               // 分为两种请求,要么candidates中包含一个required等于true的构造方法
               // 要么candidates中包含一个或多个required等于false的构造方法

               // 如果没有指定required为true的构造方法,那么就把构造方法添加到candidates中去,后续一起进行推断
               if (requiredConstructor == null) {
                  if (defaultConstructor != null) {
                     // 那么就把无参的构造方法也添加进去
                     candidates.add(defaultConstructor);
                  }
                  // 如果没有指定required为true的构造方法,并且也没有无参的构造方法,并且只有一个构造方法
                  else if (candidates.size() == 1 && logger.isInfoEnabled()) {
                     // 给一个提示,没有无参的构造方法,然后又只有一个@Autowired(required=false)的构造方法
                     // 所以其实一定会用这个构造方法,所以打印一个日志,告诉程序员,你其实可以把required改为true
                     logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
                           "': single autowire-marked constructor flagged as optional - " +
                           "this constructor is effectively required since there is no " +
                           "default constructor to fall back to: " + candidates.get(0));
                  }
               }

               // candidateConstructors就是当前方法的返回值
               // 把candidates方法,两种情况,要么只有一个@Autowired(required=true)的构造方法,要么多个@Autowired(required=false)+一个无参构造方法
               candidateConstructors = candidates.toArray(new Constructor<?>[0]);
            }
            // 没有加了@Autowired注解的构造方法,那么则判断是不是只有一个有参的构造方法,如果是则返回
            else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
               candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
            }
            // primaryConstructor != null 不管
            else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
                  defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
               candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
            }
            else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
               candidateConstructors = new Constructor<?>[] {primaryConstructor};
            }
            // 如果没有构造方法上添加了@Autowired注解,并且有多个构造方法,并且没有primaryConstructor
            else {
               // 返回一个空的Constructor数组,表示没有推断出来构造方法
               candidateConstructors = new Constructor<?>[0];
            }
            this.candidateConstructorsCache.put(beanClass, candidateConstructors);
         }
      }
   }

   // 要么返回一个required=true的构造方法
   // 要么返回多个requreid=false+无参的构造方法
   // 要么返回唯一的一个有参的构造方法
   // 如果只有一个无参的构造方法,这里会返回null,外层逻辑会默认使用无参构造方法进行实例化
   return (candidateConstructors.length > 0 ? candidateConstructors : null);
}

该方法作用为获取到构造器的候选者,该方法最终返回的内容可能有以下几种:

1. 返回一个@Autowired required=true的构造方法
2. 返回多个@Autowired requreid=false和一个没被@Autowired的无参的构造方法
3. 返回唯一的一个有参的构造方法
4. 如果只有一个无参的构造方法,这里会返回null,外层逻辑会默认使用无参构造方法进行实例化

这个方法的主要逻辑如下:

获取到构造器候选者后进入这块逻辑:

// 通过BeanPostProcessor找出了构造方法
// 或者BeanDefinition的autowire属性为AUTOWIRE_CONSTRUCTOR
// 或者BeanDefinition中指定了构造方法参数值
// 或者在getBean()时指定了args
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
      mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
   // 进行构造方法推断并实例化
   return autowireConstructor(beanName, mbd, ctors, args);
}

我们进入autowireConstructor推断构造方法中查看。

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
      @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
   // mbd当前bean的BeanDefinition
   // chosenCtors构造方法
   // explicitArgs,getBean()方法中所传递的参数

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

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

   // 是否通过getBean()方法指定了构造方法参数值
   if (explicitArgs != null) {
      argsToUse = explicitArgs;
   }
   else {
      // 从缓存中获取构造方法和构造方法参数值
      Object[] argsToResolve = null;
      synchronized (mbd.constructorArgumentLock) {
         constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;

         // 找到了mbd中缓存的构造方法
         if (constructorToUse != null && mbd.constructorArgumentsResolved) {
            // Found a cached constructor...
            argsToUse = mbd.resolvedConstructorArguments;
            if (argsToUse == null) {
               argsToResolve = mbd.preparedConstructorArguments;
            }
         }
      }
      // 如果存在构造方法参数值,那么则对参数值进行类型转化
      if (argsToResolve != null) {
         argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
      }
   }

   // 如果待使用的构造方法为null,或待使用的构造方法参数为null
   if (constructorToUse == null || argsToUse == null) {
      // Take specified constructors, if any.
      // chosenCtors表示所指定的构造方法,没有指定则获取beanClass中的所有的构造方法作为候选者,从这些构造方法中选择一个构造方法
      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);
         }
      }

      // 有了构造方法之后,则进行自动推断

      // 如果只有一个构造方法,并且没有指定构造方法参数值,则需要判断是不是无参构造方法,如果是则可以使用无参构造方法进行实例化
      if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
         Constructor<?> uniqueCandidate = candidates[0];
         if (uniqueCandidate.getParameterCount() == 0) {
            synchronized (mbd.constructorArgumentLock) {
               // 确定了构造方法之后进行缓存
               mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
               mbd.constructorArgumentsResolved = true;
               mbd.resolvedConstructorArguments = EMPTY_ARGS;
            }
            bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
            return bw;
         }
      }


      // 如果指定了多个构造方法,或者autowireMode是构造方法自动注入,则要自动选择构造方法
      // Need to resolve the constructor.
      boolean autowiring = (chosenCtors != null ||
            mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
      ConstructorArgumentValues resolvedValues = null; // 记录解析后的构造方法参数值

      int minNrOfArgs; // 表示所有构造方法中,参数个数最少的构造方法的参数个数是多少
      if (explicitArgs != null) {
         minNrOfArgs = explicitArgs.length;
      }
      else {
         // 从BeanDefinition中获取所设置的构造方法参数值
         ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
         // 记录解析后的构造方法参数值
         resolvedValues = new ConstructorArgumentValues();
         // 解析BeanDefinition中所设置的构造方法参数值(index跳跃)
         minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
      }

      // 按构造方法的参数个数降序排序,参数个数多的在前
      AutowireUtils.sortConstructors(candidates);

      int minTypeDiffWeight = Integer.MAX_VALUE;
      Set<Constructor<?>> ambiguousConstructors = null;
      LinkedList<UnsatisfiedDependencyException> causes = null;

      // 遍历构造方法,找到一个最合适的(贪婪)
      // 先看参数列表最长的构造方法,根据每个参数的参数类型和参数名去找bean
      for (Constructor<?> candidate : candidates) {
         // 当前构造方法的参数个数
         int parameterCount = candidate.getParameterCount();

         // 已经找到了一个带使用的构造方法已经参数,并且该参数个数大于当前遍历的,则不用继续遍历了
         if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
            // Already found greedy constructor that can be satisfied ->
            // do not look any further, there are only less greedy constructors left.
            break;
         }
         // 在遍历某个构造方法时,如果参数个数小于用于所指定的参数个数,则忽略该构造方法
         if (parameterCount < minNrOfArgs) {
            continue;
         }


         ArgumentsHolder argsHolder;

         // 当前遍历到的某个构造方法的参数类型
         Class<?>[] paramTypes = candidate.getParameterTypes();

         // 没有通过getBean()方法指定构造方法参数值
         if (resolvedValues != null) {
            try {
               // 获取参数名
               // 查看是否在构造方法上使用@ConstructorProperties注解来定义构造方法参数的名字
               String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
               if (paramNames == null) {
                  ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                  if (pnd != null) {
                     paramNames = pnd.getParameterNames(candidate);
                  }
               }

               // 根据当前构造方法的参数类型和参数名从beanFactory中得到bean作为参数值
               // resolvedValues表示所指定的构造方法参数值
               // paramTypes,当前构造方法的参数类型列表
               // paramNames,当前构造方法的参数值列表
               // getUserDeclaredConstructor(candidate)获取父类中被重写的构造方法
               argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                     getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
            }
            catch (UnsatisfiedDependencyException ex) {
               // 如果找不到对应的bean,也不会直接报错,只能证明当前遍历到的构造方法不能用
               if (logger.isTraceEnabled()) {
                  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 {
            // 通过getBean()方法指定了构造方法参数值

            // Explicit arguments given -> arguments length must match exactly.
            if (parameterCount != explicitArgs.length) {
               continue;
            }
            // 如果参数个数匹配,则把所有参数值封装为一个ArgumentsHolder对象
            argsHolder = new ArgumentsHolder(explicitArgs);
         }

         // 执行到这里,表示当前构造方法可用,并且也找到了对应的构造方法参数值
         // 但是还需要判断,当前构造方法是不是最合适的,也许还有另外的构造方法更合适

         // 根据参数类型和参数值计算权重
         // Lenient宽松,默认宽松模式是开启的
         // 在宽松模式下,会判断每个参数值的类型和当前构造方法的参数类型的距离
         // 在非宽松模式下,会忽略每个参数值的类型和当前构造方法的参数类型的距离,只要是父子关系距离是一样的
         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) {
            // 如果权重一样,则记录在ambiguousConstructors中,继续遍历下一个构造方法
            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)");
      }
      // 如果存在权重一样的构造方法并且不是宽松模式,也报错,因为权重一样,Spring不知道该用哪个
      // 如果是宽松模式则不会报错,Spring会用找到的第一个
      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);
      }

      // 如果不是通过getBean()方法指定的参数,那么就把找到的构造方法参数进行缓存
      if (explicitArgs == null && argsHolderToUse != null) {
         // 缓存找到的构造方法
         argsHolderToUse.storeCache(mbd, constructorToUse);
      }
   }

   // 得到了构造方法和构造方法的参数值之后,就可以进行实例化了
   Assert.state(argsToUse != null, "Unresolved constructor arguments");
   bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
   return bw;
}

推断构造方法流程图如下:

总结一下推断构造:

1.如果bd使用Supplier接口或者是@Bean方式获取bean,那么就不进行推断方法,直接返回实例。

2.确定构造方法是否已经确认推断出来了,推断出就直接使用推断出的构造器进行实例化,如果没有推断出则继续。

3.进行构造器选举,选出符合的构造器。

4.进行推断构造,如果构造方法和参数都确定则进行实例化,不符合则对候选构造器进行处理。

5.根据参数类型和参数值计算权重,选择最合适的构造器返回,完成实例化。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值