Spring createBeanInstance实例化Bean

作者:无名之辈J 时间:2023-06-17 17:26:27 

Spring实例Bean的方法

Spring实例Bean的方法,在AbstractAutowireCapableBeanFactory中的

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
  // Make sure bean class is actually resolved at this point.
  //解析Bean的类型,确认需要创建的bean实例的类可以实例化。
  //如果没有设置通过Class.forName获取Bean类型
  Class<?> beanClass = resolveBeanClass(mbd, beanName);
  // 确保class不为空,并且访问权限是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方式创建Bean: 需要先有回调Bean
   // 判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
  Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
  if (instanceSupplier != null) {
     return obtainFromSupplier(instanceSupplier, beanName);
  }
  //②FactoryMethod方式创建Bean: 需要在XML中配置factory-method
  // 判断是否有工厂方法,如果存在,会尝试调用该Bean定义信息中的工厂方法来获取实例
  if (mbd.getFactoryMethodName() != null) {
     return instantiateUsingFactoryMethod(beanName, mbd, args);
  }
  // Shortcut when re-creating the same bean...
  //一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器,当多次构建同一个 bean 时就不需要重新判断应该使用那种方式构造Bean
  boolean resolved = false;
  //是否需要自动装配
  boolean autowireNecessary = false;
  if (args == null) {
     synchronized (mbd.constructorArgumentLock) {
       // 因为判断过程会比较,所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
       // 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析,导致循环依赖
        if (mbd.resolvedConstructorOrFactoryMethod != null) {
           //标识以及解析过class的构造器
           resolved = true;
           autowireNecessary = mbd.constructorArgumentsResolved;
        }
     }
  }
  // 有构造参数的或者工厂
  if (resolved) {
      //已经解析过class的构造器,使用已经解析好的构造器
     if (autowireNecessary) {
        //构造函数自动注入
        return autowireConstructor(beanName, mbd, null, null);
     }
     else {
        //使用默认构造器
        return instantiateBean(beanName, mbd);
     }
  }
  // Candidate constructors for autowiring?
  // 从bean后置处理器中为自动装配寻找构造方法
  // 以下情况符合其一即可进入
  // 1、存在可选构造方法
  // 2、自动装配模型为构造函数自动装配
  // 3、给BeanDefinition中设置了构造参数值
  // 4、有参与构造函数参数列表的参数
  //一、确定构造参数
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
     return autowireConstructor(beanName, mbd, ctors, args);
  }
  // Preferred constructors for default construction?
  // 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造
  ctors = mbd.getPreferredConstructors();
 if (ctors != null) {
     // 构造函数自动注入
     // 二、有参构造创建Bean
     return autowireConstructor(beanName, mbd, ctors, null);
  }
  // No special handling: simply use no-arg constructor.
  // 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
  //三、无参构造创建Bean
  return instantiateBean(beanName, mbd);
}

①:Supplier方式创建Bean:5、Spring源码之Supplier

②:FactoryMethod方式创建Bean: 【Spring源码】8.IOC之创建bean对象之FactoryMethod

③:自动装配类型

  • int AUTOWIRE_NO = 0;//表示没有外部定义的自动装配

  • int AUTOWIRE_BY_NAME = 1;//通过名称指示自动装配bean属性(适用于Bean所有属性的setter)

  • int AUTOWIRE_BY_TYPE = 2;//通过类型指示自动装配bean属性(适用于Bean所有属性的setter)

  • int AUTOWIRE_CONSTRUCTOR = 3;//构造函数

  • int AUTOWIRE_AUTODETECT = 4;//通过bean类的内省确定适当的自动装配策略,在Spring3.0之后已经不再支持。

  • String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";//用于没有代理的时候,也能强制返回实例

一、determineConstructorsFromBeanPostProcessors:确定构造参数

实现父类SmartInstantiationAwareBeanPostProcessor后置处理器的determineCandidateConstructors方法

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
     throws BeansException {
  if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
     for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
           SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
           //执行后置处理器,确定构造函数
           Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
           if (ctors != null) {
              return ctors;
           }
        }
     }
  }
  return null;
}

这里会通过AutowiredAnnotationBeanPostProcessor后置处理器确定构造函数

详情:https://www.jb51.net/article/277330.htm

二、autowireConstructor:有参构造创建Bean

创建构造器解析器自动写入构造函数

protected BeanWrapper autowireConstructor(
     String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
  return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
     @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
  //实例化BeanWrapper,是包 * ean的容器
  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;
        //获取缓存中的构造器
        if (constructorToUse != null && mbd.constructorArgumentsResolved) {
           // Found a cached constructor...
           //在缓存中找到了构造器,就继续从缓存中寻找缓存的构造器参数
           argsToUse = mbd.resolvedConstructorArguments;
           if (argsToUse == null) {
              //构造器中没有缓存的参数,就需要获取配置文件中配置的参数
              argsToResolve = mbd.preparedConstructorArguments;
           }
        }
     }
     //如果有构造器但是构造器中没有参数,就需要解析构造参数
     if (argsToResolve != null) {
        //解析参数类型,比如将配置的String类型转换成int、boolean等类型
        argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
     }
  }
  //如果没有缓存,就需要先解析构造函数
  if (constructorToUse == null || argsToUse == null) {
     // Take specified constructors, if any.
     // 如果传入的构造器数组不为空,就使用传入的构造器参数,否则通过反射获取class中定义的构造器
     Constructor<?>[] candidates = chosenCtors;
     if (candidates == null) {
        Class<?> beanClass = mbd.getBeanClass();
        try {
           //通过反射获取class中定义的构造器
           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);
        }
     }
     //如果只有一个构造函数并且参数值为null,则直接使用无参构造器实例化
     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;
        }
     }
     // 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 {
        //获取构造参数值
        ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
        resolvedValues = new ConstructorArgumentValues();
        //2.1 解析参数并返回最小参数个数
        minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
     }
     //给构造函数排序,public构造函数优先、参数数量降序排序  
     AutowireUtils.sortConstructors(candidates);
     int minTypeDiffWeight = Integer.MAX_VALUE;
     Set<Constructor<?>> ambiguousConstructors = null;
     LinkedList<UnsatisfiedDependencyException> causes = null;
     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();
        //需要解析的参数值不为空
        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);
                 }
              }
              //根据获取到的参数名和已经查到的构造参数和构造参数类型来创建用户创建构造器用的构造参数数组
              //这个数组中包含了原始的参数列表和构造后的参数列表,用来对比用
              //2.2 创建构造参数数组
              argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                    getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
           }
           catch (UnsatisfiedDependencyException ex) {
              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 {
           // Explicit arguments given -> arguments length must match exactly.
           if (parameterCount != explicitArgs.length) {
              continue;
           }
           argsHolder = new ArgumentsHolder(explicitArgs);
        }
        //如果是宽松的构造策略,则对比spring构造的参数数组的类型和获取到的构造器参数的参数类型进行对比,返回不同的个数
        //如果是严格的构造策略,则检查能否将构造的参数数组赋值到构造器参数的参数列表中
        int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
              argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
        // Choose this constructor if it represents the closest match.
        // 当前构造函数最为匹配的话,清空先前ambiguousConstructors列表
        if (typeDiffWeight < minTypeDiffWeight) {
           constructorToUse = candidate;
           argsHolderToUse = argsHolder;
           argsToUse = argsHolder.arguments;
           minTypeDiffWeight = typeDiffWeight;
           ambiguousConstructors = null;
        }
        //存在相同权重的构造器,将构造器添加到一个ambiguousConstructors列表变量中
//注意,这时候constructorToUse 指向的仍是第一个匹配的构造函数
        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);
     }
     //缓存参数构造器,下次创建直接使用
     //并设置constructorArgumentsResolved为true,表示已经解析过构造函数
     if (explicitArgs == null && argsHolderToUse != null) {
        argsHolderToUse.storeCache(mbd, constructorToUse);
     }
  }
  Assert.state(argsToUse != null, "Unresolved constructor arguments");
  //2.3 实例化Bean
  bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
  return bw;
}

2.1 resolveConstructorArguments:解析参数并返回最小参数个数

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
     ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
  // 是否有定制的类型转换器,没有的话直接使用BeanWrapper进行类型转换
  TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
  TypeConverter converter = (customConverter != null ? customConverter : bw);
  // 构造一个BeanDefinitionValueResolver,专门用于解析constructor-arg中的value属性,实际上还包括ref属性,内嵌bean标签等等
  BeanDefinitionValueResolver valueResolver =
        new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
   // minNrOfArgs 记录执行方法要求的最小参数个数,一般情况下就是等于constructor-arg标签指定的参数数量
  int minNrOfArgs = cargs.getArgumentCount();
  for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
     int index = entry.getKey();
     if (index < 0) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
              "Invalid constructor argument index: " + index);
     }
     // 假设A方法直接在配置文件中指定了index=3上要使用的参数,那么这个时候A方法至少需要4个参数
     // 但是其余的3个参数可能不是通过constructor-arg标签指定的,而是直接自动注入进来的,那么在配置文件中我们就只配置了index=3上的参数,也就是说 int minNrOfArgs = cargs.getArgumentCount()=1,这个时候 index=3,minNrOfArgs=1, 所以 minNrOfArgs = 3+1
     if (index + 1 > minNrOfArgs) {
        minNrOfArgs = index + 1;
     }
     ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
     // 如果已经转换过了,直接添加到resolvedValues集合中
     if (valueHolder.isConverted()) {
        resolvedValues.addIndexedArgumentValue(index, valueHolder);
     }
     else {
        // 解析value/ref/内嵌bean标签等
        Object resolvedValue =
              valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
         // 将解析后的resolvedValue封装成一个新的ValueHolder,
 // 并将其source设置为解析constructor-arg得到的那个ValueHolder,
 // 后期会用到这个属性进行判断
        ConstructorArgumentValues.ValueHolder resolvedValueHolder =
              new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
        resolvedValueHolder.setSource(valueHolder);
        resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
     }
  }
  // 对getGenericArgumentValues进行解析
  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;
}

2.2 createArgumentArray:创建构造参数数组

private ArgumentsHolder createArgumentArray(
       String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
       BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
       boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
   TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
   TypeConverter converter = (customConverter != null ? customConverter : bw);
   ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
   Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
   Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
   for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
       Class<?> paramType = paramTypes[paramIndex];
       String paramName = (paramNames != null ? paramNames[paramIndex] : "");
       // Try to find matching constructor argument value, either indexed or generic.
       // 尝试找到匹配的构造函数参数值,无论是索引的还是泛型的。
       ConstructorArgumentValues.ValueHolder valueHolder = null;
       if (resolvedValues != null) {
           valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
           // If we couldn't find a direct match and are not supposed to autowire,
           // let's try the next generic, untyped argument value as fallback:
           // it could match after type conversion (for example, String -> int).
           // 如果我们找不到直接匹配并且不应该自动装配,让我们尝试下一个通用的、无类型的参数值作为后备:它可以在类型转换后匹配(例如,String -> int)。
           if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
               valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
           }
       }
       if (valueHolder != null) {
           // We found a potential match - let's give it a try.
           // Do not consider the same value definition multiple times!
           // 我们找到了一个潜在的匹配 - 让我们试一试。不要多次考虑相同的值定义!
           usedValueHolders.add(valueHolder);
           Object originalValue = valueHolder.getValue();
           Object convertedValue;
           if (valueHolder.isConverted()) {
               convertedValue = valueHolder.getConvertedValue();
               args.preparedArguments[paramIndex] = convertedValue;
           }
           else {
               MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
               try {
                   convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
               }
               catch (TypeMismatchException ex) {
                   throw new UnsatisfiedDependencyException(
                           mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                           "Could not convert argument value of type [" +
                                   ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
                                   "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
               }
               Object sourceHolder = valueHolder.getSource();
               if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
                   Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
                   args.resolveNecessary = true;
                   args.preparedArguments[paramIndex] = sourceValue;
               }
           }
           args.arguments[paramIndex] = convertedValue;
           args.rawArguments[paramIndex] = originalValue;
       }
       else {
           // 这部分就是超出了参数定义,需要自动注入参数的处理
           MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
           // No explicit match found: we're either supposed to autowire or
           // have to fail creating an argument array for the given constructor.
           if (!autowiring) {
               throw new UnsatisfiedDependencyException(
                       mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                       "Ambiguous argument values for parameter of type [" + paramType.getName() +
                               "] - did you specify the correct bean references as arguments?");
           }
           try {
               Object autowiredArgument = resolveAutowiredArgument(
                       methodParam, beanName, autowiredBeanNames, converter, fallback);
               args.rawArguments[paramIndex] = autowiredArgument;
               args.arguments[paramIndex] = autowiredArgument;
               args.preparedArguments[paramIndex] = autowiredArgumentMarker;
               args.resolveNecessary = true;
           }
           catch (BeansException ex) {
               throw new UnsatisfiedDependencyException(
                       mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
           }
       }
   }
   for (String autowiredBeanName : autowiredBeanNames) {
       this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
       if (logger.isDebugEnabled()) {
           logger.debug("Autowiring by type from bean name '" + beanName +
                   "' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
                   " to bean named '" + autowiredBeanName + "'");
       }
   }
   return args;
}

2.3 instantiate:实例化Bean

private Object instantiate(String beanName, RootBeanDefinition mbd,
                          @Nullable Object factoryBean, Method factoryMethod, Object[] args) {
   try {
       if (System.getSecurityManager() != null) {
           return AccessController.doPrivileged((PrivilegedAction&lt;Object&gt;) () -&gt;
                           this.beanFactory.getInstantiationStrategy().instantiate(
                                   mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
                   this.beanFactory.getAccessControlContext());
       }
       else {
           //四、使用实例化策略创建Bean
           return this.beanFactory.getInstantiationStrategy().instantiate(
                   mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
       }
   }
   catch (Throwable ex) {
       throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Bean instantiation via factory method failed", ex);
   }
}

三、instantiateBean:无参构造创建Bean

无参构造

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>) () ->
                           getInstantiationStrategy().instantiate(mbd, beanName, parent),
                   getAccessControlContext());
       }
       else {
           // 使用默认的实例化策略来实例化对象,默认为 CglibSubclassingInstantiationStrategy 实现,但是instantiate()方法只在SimpleInstantiationStrategy里有实现逻辑
           //四、使用实例化策略创建Bean
           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

这里会进入SimpleInstantiationStrategy的instantiate方法

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
     final Constructor<?> ctor, Object... args) {
   //在将 XML 配置解析成 BeanDefinition 的时候,bean标签的lookup-method和replaced-method会被分别解析成 LookupOverride 和 ReplaceOverride 对象
  //添加到 BeanDefinition 的methodOverrides成员变量中
  //如果没有配置就会走当前这个流程
  if (!bd.hasMethodOverrides()) {
     if (System.getSecurityManager() != null) {
        // use own privileged to change accessibility (when security is on)
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
           ReflectionUtils.makeAccessible(ctor);
           return null;
        });
     }
     //4.1、反射创建Bean
     return BeanUtils.instantiateClass(ctor, args);
  }
  else {
     //如果方法被覆盖,通过Cglib实现代理类
     //4.2、Cglib创建代理类
     return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
  }
}

4.1、反射创建Bean

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
  Assert.notNull(ctor, "Constructor must not be null");
  try {
     //设置访问权限
     ReflectionUtils.makeAccessible(ctor);
     if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
        return KotlinDelegate.instantiateClass(ctor, args);
     }
     else {
        Class<?>[] parameterTypes = ctor.getParameterTypes();
        Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
        Object[] argsWithDefaultValues = new Object[args.length];
        //初始化参数
        for (int i = 0 ; i < args.length; i++) {
           if (args[i] == null) {
              Class<?> parameterType = parameterTypes[i];
              argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
           }
           else {
              argsWithDefaultValues[i] = args[i];
           }
        }
        return ctor.newInstance(argsWithDefaultValues);
     }
  }
  catch (InstantiationException ex) {
     throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
  }
  catch (IllegalAccessException ex) {
     throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
  }
  catch (IllegalArgumentException ex) {
     throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
  }
  catch (InvocationTargetException ex) {
     throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
  }
}

4.2、Cglib创建代理类

@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
     @Nullable Constructor<?> ctor, Object... args) {
  // Must generate CGLIB subclass...
  return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}

创建Cglib代理类

public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
  //创建Cglib增强子类
  Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
  Object instance;
  if (ctor == null) {
     //4.1 反射创建Bean
     instance = BeanUtils.instantiateClass(subclass);
  }
  else {
     try {
        //反射创建Bean
        Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
        instance = enhancedSubclassConstructor.newInstance(args);
     }
     catch (Exception ex) {
        throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
              "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
     }
  }
  // SPR-10785: set callbacks directly on the instance instead of in the
  // enhanced class (via the Enhancer) in order to avoid memory leaks.
  Factory factory = (Factory) instance;
  factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
        new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
        new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
  return instance;
}
  • 将所有的候选构造函数排序,排序规则[第一排序规则: public方法优先,第二排序规则:参数数量降序]

  • 设置一个算法,输入构造函数,输出一个整数

  • 判断构造方法能否完成依赖注入,不能跳过该构造函数

  • 算法输出的最小值则作为被选中的构造函数

  • 通过选中的构造函数完成对象实例化

  • 算法根据mbd.isLenientConstructorResolution(默认宽松模式)区分严格模式和宽松模式,不同的模式有不同计算方式

来源:https://juejin.cn/post/7206331674295697467

标签:Spring,createBeanInstance,实例化
0
投稿

猜你喜欢

  • java IO流将一个文件拆分为多个子文件代码示例

    2023-08-30 12:46:15
  • Android自定义控件实现时间轴

    2021-07-12 04:13:08
  • SpringBoot如何使用applicationContext.xml配置文件

    2022-11-15 08:18:53
  • C#、ASP.NET通用扩展工具类之LogicSugar

    2023-11-18 09:56:07
  • Java多线程、进度条实现赛马实验的示例代码

    2023-08-20 04:44:10
  • Java使用线程同步解决线程安全问题详解

    2022-02-28 02:03:24
  • SpringBoot集成Caffeine缓存的实现步骤

    2023-08-23 05:44:11
  • Java Comparable和Comparator对比详解

    2022-08-13 01:28:08
  • Android使用AIDL方式实现播放音乐案例

    2022-01-04 23:58:40
  • C#中C/S端实现WebService服务

    2023-10-16 06:01:43
  • C#实现简化QQ聊天窗口

    2023-01-18 19:01:20
  • Android中使用Kotlin实现一个简单的登录界面

    2023-01-29 13:51:37
  • Kotlin扩展方法超详细介绍

    2023-05-31 16:31:23
  • Android实现签名涂鸦手写板

    2022-07-27 04:10:14
  • 解决@Autowired注入static接口的问题

    2022-01-02 03:16:29
  • 浅谈抛出异常和捕获异常的一些区别

    2023-10-19 15:25:24
  • Android 沉浸式改变小米魅族状态栏颜色的实例代码

    2023-11-18 15:13:16
  • Java实现经典游戏黄金矿工的示例代码

    2022-01-09 16:35:41
  • Springboot webscoket自定义定时器

    2023-02-12 05:34:02
  • springboot的类加载器(org.springframework.boot.loader)过程详解

    2021-05-23 21:01:44
  • asp之家 软件编程 m.aspxhome.com