本文作者:chenssy
出处:http://cmsblogs.com/?p=2850
在学习Spring源码的过程中发现的好站+好贴,感谢作者。Spring版本:Spring 5.0.6.RELEASE
createBeanInstance() 用于实例化 bean,它会根据不同情况选择不同的实例化策略来完成 bean 的初始化,主要包括:
- Supplier 回调:
obtainFromSupplier() 
- 工厂方法初始化:
instantiateUsingFactoryMethod() 
- 构造函数自动注入初始化:
autowireConstructor() 
- 默认构造函数注入:
instantiateBean() 
在( IOC 之 Factory 实例化 bean) 中分析了 Supplier 回调和工厂方法初始化,这篇分析两个构造函数注入。
autowireConstructor()
这个初始化方法我们可以简单理解为是带有参数的初始化 bean 。代码段如下:
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) {                  argsToUse = mbd.resolvedConstructorArguments;         if (argsToUse == null) {           argsToResolve = mbd.preparedConstructorArguments;         }       }     }
                     if (argsToResolve != null) {       argsToUse =          resolvePreparedArguments(beanName, mbd, bw,                                   constructorToUse, argsToResolve);     }   }
    
 
    if (constructorToUse == null) {          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);     }
      
 
           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) {         break;       }              if (paramTypes.length < minNrOfArgs) {         continue;       }
               ArgumentsHolder argsHolder;              if (resolvedValues != null) {         try {                      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);           }                      if (causes == null) {             causes = new LinkedList<>();           }           causes.add(ex);           continue;         }       }       else {                  if (paramTypes.length != explicitArgs.length) {           continue;         }         argsHolder = new ArgumentsHolder(explicitArgs);       }
                                    int typeDiffWeight = (mbd.isLenientConstructorResolution() ?            argsHolder.getTypeDifferenceWeight(paramTypes) :                             argsHolder.getAssignabilityWeight(paramTypes));
               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 {          final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();     Object beanInstance;
      if (System.getSecurityManager() != null) {       final Constructor<?> ctorToUse = constructorToUse;       final Object[] argumentsToUse = argsToUse;              beanInstance =          AccessController.doPrivileged(         (PrivilegedAction<Object>) () ->         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);   } }
   | 
 
代码与 instantiateUsingFactoryMethod() 一样,又长又难懂,但是如果理解了 instantiateUsingFactoryMethod() 初始化 bean 的过程,那么 autowireConstructor() 也不存在什么难的地方了,一句话概括:首先确定构造函数参数、构造函数,然后调用相应的初始化策略进行 bean 的初始化。关于如何确定构造函数、构造参数,该部分逻辑和 instantiateUsingFactoryMethod() 基本一致,所以这里不再重复阐述了,具体过程请移步IOC 之 Factory 实例化 bean,这里我们重点分析初始化策略。 对于初始化策略,首先是获取实例化 bean 的策略,如下:
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
   | 
 
然后是调用其 instantiate()方法,该方法在 SimpleInstantiationStrategy 中实现,如下:
public Object instantiate(   RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {         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 {          return instantiateWithMethodInjection(bd, beanName, owner);   } }
   | 
 
如果该 bean 没有配置 lookup-method、replaced-method 标签或者 @Lookup 注解,则直接通过反射的方式实例化 bean 即可,方便快捷,但是如果存在需要覆盖的方法或者动态替换的方法则需要使用 CGLIB 进行动态代理,因为可以在创建代理的同时将动态方法织入类中。 反射 调用工具类 BeanUtils 的 instantiateClass() 方法完成反射工作:
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {   Assert.notNull(ctor, "Constructor must not be null");   try {     ReflectionUtils.makeAccessible(ctor);     return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?             KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));   }    }
  | 
 
CGLIB
protected Object instantiateWithMethodInjection(   RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {   throw new UnsupportedOperationException(     "Method Injection not supported in SimpleInstantiationStrategy"); }
   | 
 
方法默认是没有实现的,具体过程由其子类 CglibSubclassingInstantiationStrategy 实现:
protected Object instantiateWithMethodInjection(   RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {   return instantiateWithMethodInjection(bd, beanName, owner, null); }
  protected Object instantiateWithMethodInjection   (RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,    @Nullable Constructor<?> ctor, @Nullable Object... args) {
       return new CglibSubclassCreator(bd, owner).instantiate(ctor, args); }
   | 
 
创建一个 CglibSubclassCreator 对象,调用其 instantiate() 方法生成其子类对象:
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {      Class<?> subclass = createEnhancedSubclass(this.beanDefinition);   Object instance;      if (ctor == null) {     instance = BeanUtils.instantiateClass(subclass);   }   else {     try {              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);     }   }
       Factory factory = (Factory) instance;   factory.setCallbacks(new Callback[] {     NoOp.INSTANCE,     new CglibSubclassingInstantiationStrategy       .LookupOverrideMethodInterceptor(       this.beanDefinition, this.owner),     new CglibSubclassingInstantiationStrategy       .ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});   return instance; }
  | 
 
到这类 CGLIB 的方式分析完毕了,当然这里还没有具体分析 CGLIB 生成子类的详细过程,具体的过程等后续分析 AOP 的时候再详细地介绍。
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>) () ->                       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);   } }
   | 
 
这个方法相比于 instantiateUsingFactoryMethod() 、 autowireConstructor() 方法实在是太简单了,因为它没有参数,所以不需要确认经过复杂的过来来确定构造器、构造参数,所以这里就不过多阐述了。 
对于 createBeanInstance() 而言,他就是选择合适实例化策略来为 bean 创建实例对象,具体的策略有:Supplier 回调方式、工厂方法初始化、构造函数自动注入初始化、默认构造函数注入。
其中工厂方法初始化和构造函数自动注入初始化两种方式最为复杂,主要是因为构造函数和构造参数的不确定性,Spring 需要花大量的精力来确定构造函数和构造参数,如果确定了则好办,直接选择实例化策略即可。当然在实例化的时候会根据是否有需要覆盖或者动态替换掉的方法,因为存在覆盖或者织入的话需要创建动态代理将方法织入,这个时候就只能选择 CGLIB 的方式来实例化,否则直接利用反射的方式即可,方便快捷。 到这里 createBeanInstance() 的过程就已经分析完毕了。