Spring源码解析6——bean的加载(二)

8、创建Bean(接Spring源码解析5——bean的加载(一) 中标题6、创建ObjectFactory<?>.java类型的实例(准备创建Bean)的第④步)

  当经历了AbstractAutowireCapableBeanFactory.java:createBean() 中的 AbstractAutowireCapableBeanFactory.java:resolveBeforeInstantiation() 函数后,程序会有两个选择:
①、如果创建了代理或者说重写了InstantiationAwareBeanPostProcessor.java:postProcessBeforeInstantiation()函数,并在 InstantiationAwareBeanPostProcessor.java:postProcessBeforeInstantiation()函数中改变了bean,则直接返回就可以了,AOP就是基于这个原理。
②、否则需要常规的bean的创建,而常规bean的创建就是在AbstractAutowireCapableBeanFactory.java:createBean() 中的 AbstractAutowireCapableBeanFactory.java:doCreateBean()函数中完成的。
AbstractAutowireCapableBeanFactory.java:doCreateBean()(常规bean的创建)

/**
 * Actually create the specified bean. Pre-creation processing has already happened
 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
 * <p>Differentiates between default bean instantiation, use of a
 * factory method, and autowiring a constructor.
 * @param beanName the name of the bean
 * @param mbd the merged bean definition for the bean
 * @param args explicit arguments to use for constructor or factory method invocation
 * @return a new instance of the bean
 * @throws BeanCreationException if the bean could not be created
 * @see #instantiateBean
 * @see #instantiateUsingFactoryMethod
 * @see #autowireConstructor
 */
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      //根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化。
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         //应用MergedBeanDefinitionPostProcessor
         try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }

   // Eagerly cache singletons to be able to resolve circular references
   // even when triggered by lifecycle interfaces like BeanFactoryAware.
   //是否需要提早曝光:单例&允许循环依赖&当前Bean正在创建中
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      if (logger.isDebugEnabled()) {
         logger.debug("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      //为了避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//λ表达式:匿名内部类
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      //对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖bean
      populateBean(beanName, mbd, instanceWrapper);
      //调用初始化方法,比如init-method
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }

   if (earlySingletonExposure) {
      Object earlySingletonReference = getSingleton(beanName, false);
      //earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
      if (earlySingletonReference != null) {
         //如果exposeObject没有在初始化方法中被改变,也就是没有初始化
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               //检测依赖
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
            //因为bean创建后,其所依赖的bean一定是已经创建的,actualDependentBeans不为空则表示当前bean创建后,
            //                       其依赖的bean却没有被全部创建完,也就是说存在循环依赖
            if (!actualDependentBeans.isEmpty()) {
               throw new BeanCurrentlyInCreationException(beanName,
                     "Bean with name '" + beanName + "' has been injected into other beans [" +
                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                     "] in its raw version as part of a circular reference, but has eventually been " +
                     "wrapped. This means that said other beans do not use the final version of the " +
                     "bean. This is often the result of over-eager type matching - consider using " +
                     "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
            }
         }
      }
   }

   // Register bean as disposable.
   try {
      //根据scope注册bean
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}

以上逻辑概要:
①、如果是单例则需要首先清除缓存。
②、实例化bean ,将BeanDefinition 转换为BeanWrapper 。(8.1、创建bean的实例,详解)

  • 如果存在工厂方法则使用工厂方法进行初始化。
  • 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化。
  • 如果既不存在工厂方法,也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化。
    ③、MergedBeanDefinitionPostProcessor.java的应用,bean合并后的处理,@Autowired注解正是通过此方法实现类型的预解析。
    ④、循环依赖提前处理,把ObjectFactory放入缓存中(DefaultSingletonBeanRegistry.java:singletonFactories属性),这样就可以解决循环依赖。
    ⑤、属性填充,将所有属性填充至bean的实例中。
    ⑥、循环依赖检查。
    ⑦、注册DisposableBean。如果配置了destroy-method,这里需要注册以便于在销毁时候调用。
    ⑧、完成创建并返回。
8.1、创建bean 的实例(逻辑②详解)
/**
 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
 * factory method, constructor autowiring, or simple instantiation.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @param args explicit arguments to use for constructor or factory method invocation
 * @return a BeanWrapper for the new instance
 * @see #obtainFromSupplier
 * @see #instantiateUsingFactoryMethod
 * @see #autowireConstructor
 * @see #instantiateBean
 */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // Make sure bean class is actually resolved at this point.
   //解析Class
   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());
   }

   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
   if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
   }
   //如果工厂方法不为空,则使用工厂方法初始化策略
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // Shortcut when re-creating the same bean...
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         //一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要先根据参数锁定构造函数或对应的工厂方法
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   //如果已经解析过则使用解析好的构造函数方法,不需要再次锁定
   if (resolved) {
      if (autowireNecessary) {
         //构造函数自动注入
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
         //使用默认构造函数构造
         return instantiateBean(beanName, mbd);
      }
   }

   // Candidate constructors for autowiring?
   //需要根据参数解析构造函数
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      //构造函数自动注入
      return autowireConstructor(beanName, mbd, ctors, args);
   }

   // No special handling: simply use no-arg constructor.
   //使用默认构造函数构造
   return instantiateBean(beanName, mbd);
}

以上逻辑概要:
①、如果在RootBeanDefinition 中存在factoryMethodName 属性,或者说在配置文件中配置了factory-method ,那么Spring 会尝试使用AbstractAutowireCapableBeanFactory.java:instantiateUsingFactoryMethod()方法根据RootBeanDefinition.java类型的实例,配置生成BeanWrapper.java类型的的实例bean。
②、解析构造函数并进行构造函数的实例化。因为一个bean 对应的类中可能会有多个构造函数,而每个构造函数的参数不同, Spring 在根据参数及类型去判断最终会使用哪个构造函数进行实例化。但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过则不需要重复解析而是直接从RootBeanDefinition 中的属性resoIvedConstructorOrFactoryMethod 缓存的值去取,否则需要再次解析, 并将解析的结果添加至RootBeanDefinition 中的属性resolvedConstructorOrFactoryMethod 中。(8.1.1、ConstructorResolver.java:autowireConstructor(),详解)

8.1.1、ConstructorResolver.java:autowireConstructor()(逻辑②详解)

  对于实例的创建Spring 中分成了两种情况,一种是通用的实例化,另一种是带有参数的实例化。带有参数的实例化过程相当复杂,因为存在着不确定性,所以在判断对应参数上做了大量工作。

/**
 * "autowire constructor" (with constructor arguments by type) behavior.
 * Also applied if explicit constructor argument values are specified,
 * matching all remaining arguments with beans from the bean factory.
 * <p>This corresponds to constructor injection: In this mode, a Spring
 * bean factory is able to host components that expect constructor-based
 * dependency resolution.
 * @param beanName the name of the bean
 * @param mbd the merged bean definition for the bean
 * @param chosenCtors chosen candidate constructors (or {@code null} if none)
 * @param explicitArgs argument values passed in programmatically via the getBean method,
 * or {@code null} if none (-> use constructor argument values from bean definition)
 * @return a BeanWrapper for the new instance
 */
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
      @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

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

   Constructor<?> constructorToUse = null;
   ArgumentsHolder argsHolderToUse = null;
   Object[] argsToUse = null;
   //expliciArgs通过getBean方法传入
   //如果getBean方法调用的时候指定方法参数那么直接使用
   if (explicitArgs != null) {
      argsToUse = explicitArgs;
   }
   else {
      //如果在getBean方法时候没有指定则尝试从配置文件中解析
      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) {
         //解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
         //缓存中的值可能是原始值也可能是最终值
         argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
      }
   }

   //没有被缓存
   if (constructorToUse == null) {
      // 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();
         //能解析到的参数个数,指定构造函数中某个值为原始类型String类型,或者是一个对其他bean 的引用,返回能解析到的参数的个数
         minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
      }

      // Take specified constructors, if any.
      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);
         }
      }
      //排序给定的构造函数,public构造函数优先参数数量降序、非public构造函数参数数量降序
      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) {
            // Already found greedy constructor that can be satisfied ->
            // do not look any further, there are only less greedy constructors left.
            //如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止,
            //因为已经按照参数个数降序排列。
            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 (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 (paramTypes.length != explicitArgs.length) {
               continue;
            }
            //构造函数没有参数的情况
            argsHolder = new ArgumentsHolder(explicitArgs);
         }
         //探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
         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) {
            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);
      }
      //将构建的实例加入BeanWrapper中
      bw.setBeanInstance(beanInstance);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean instantiation via constructor failed", ex);
   }
}

以上逻辑概要:
①、构造函数参数确定

  • 根据explicitArgs 参数判断。
      如果传人的参数explicitArgs 不为空,那便可以直接确定参数,因为explicitArgs 参数是在调用Bean 的时候用户指定的,在BeanFactory 类中存在这样的方法:
  • Object getBean(String name , Object .. args) throws BeansException ;
      在获取bean 的时候,用户不但可以指定bean 的名称还可以指定bean 所对应类的构造函数或者工厂方法的方法参数,主要用于静态工厂方法的调用,而这里是需要给定完全匹配的参数的,所以,便可以判断,如果传人参数explicitArgs 不为空,则可以确定构造函数参数就是它。
  • 缓存中获取
      除此之外,确定参数的办法如果之前已经分析过, 也就是说构造函数参数已经记录在缓存中,那么便可以直接拿来使用。而且,这里要提到的是,在缓存中缓存的可能是参数的最终类型也可能是参数的初始类型,例如:构造函数参数要求的是int 类型,但是原始的参数值可能是String 类型的“ 1 ” ,那么即使在缓存中得到了参数,也需要经过类型转换器的过滤以确保参数类型与对应的构造函数参数类型完全对应。
  • 配置文件获取
      如果不能根据传人的参数explicitArgs 确定构造函数的参数也无法在缓存中得到相关信息,那么只能开始新一轮的分析了。分析从获取配置文件中配置的构造函数信息开始,经过之前的分析,我们知道, Spring 中配置文件中的信息经过转换都会通过BeanDefinition 实例承载,也就是参数mbd 中包含,那么可以通过调用mbd.getConstructorArgumentValues()来获取配置的构造函数信息。有了配置中的信息便可以获取对应的参数值信息了,获取参数值的信息包括直接指定值,如:直接指定构造函数中某个值为原始类型String 类型,或者是一个对其他bean 的引用,而这一处理委托给resoIveConstructorArguments() 方法,并返回能解析到的参数的个数。
    ②、构造函数的确定
      经过了第一步后已经确定了构造函数的参数,接下来的任务就是根据构造函数参数在所有构造函数中锁定对应的构造函数,而匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对构造函数按照public 构造函数优先参数数量降序、非 public 构造函数参数数量降序。这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件。
      由于在配置文件中并不是唯一限制使用参数位置索引的方式去创建,同样还支持指定参数名称进行设定参数值的情况,如<constructor-arg name="aa">,那么这种情况就需要首先确定构造函数中的参数名称。
      获取参数名称可以有两种方式,一种是通过注解的方式直接获取, 另一种就是使用Spring中提供的工具类ParameterNameDiscoverer.java 来获取。构造函数、参数名称、参数类型、参数值都确定后就可以锁定构造函数以及转换对应的参数类型了。
    ③、根据确定的构造函数转换对应的参数类型
      主要是使用Spring 中提供的类型转换器或者用户提供的自定义类型转换器进行转换。
    ④、构造函数不确定性的验证
      当然,有时候即使构造函数、参数名称、参数类型、参数值都确定后也不一定会直接锁定构造函数,不同构造函数的参数为父子关系,所以Spring 在最后又做了一次验证。
    ⑤、根据实例化策略以及得到的构造函数及构造函数参数实例化Bean。(8.1.2、实例化策略,详解)
8.1.2、实例化策略(逻辑⑤详解)

SimpleInstantiationStrategy.java:instantiate()

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
      final Constructor<?> ctor, @Nullable Object... args) {
   //如果需要覆盖或者动态替换的方法,则当然需要使用cglib进行动态代理,因为可以在创建代理的同时
   //将动态方法织入类中
   //但是如果没有需要动态改变得方法,为了方便直接反射就可以了
   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;
         });
      }
      return (args != null ? BeanUtils.instantiateClass(ctor, args) : BeanUtils.instantiateClass(ctor));
   }
   else {
       //调用子类CglibSubclassingInstantiationStrategy.java中的instantiateWithMethodInjection()函数
      return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
   }
}

CglibSubclassingInstantiationStrategy.java:instantiateWithMethodInjection()

@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
      @Nullable Constructor<?> ctor, @Nullable Object... args) {

   // Must generate CGLIB subclass...
   return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}


/**
 * An inner class created for historical reasons to avoid external CGLIB dependency
 * in Spring versions earlier than 3.2.
 */
private static class CglibSubclassCreator {

   private static final Class<?>[] CALLBACK_TYPES = new Class<?>[]
         {NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};

   private final RootBeanDefinition beanDefinition;

   private final BeanFactory owner;

   CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
      this.beanDefinition = beanDefinition;
      this.owner = owner;
   }

   /**
    * Create a new instance of a dynamically generated subclass implementing the
    * required lookups.
    * @param ctor constructor to use. If this is {@code null}, use the
    * no-arg constructor (no parameterization, or Setter Injection)
    * @param args arguments to use for the constructor.
    * Ignored if the {@code ctor} parameter is {@code null}.
    * @return new instance of the dynamically generated subclass
    */
   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);
         }
      }
      // 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;
   }

   /**
    * Create an enhanced subclass of the bean class for the provided bean
    * definition, using CGLIB.
    */
   private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
      Enhancer enhancer = new Enhancer();
      enhancer.setSuperclass(beanDefinition.getBeanClass());
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
      if (this.owner instanceof ConfigurableBeanFactory) {
         ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
         enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
      }
      enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
      enhancer.setCallbackTypes(CALLBACK_TYPES);
      return enhancer.createClass();
   }
}

clipboard

  看了上面两个函数后似乎我们已经感受到了Spring 的良苦用心以及为了能更方便地使用Spring 而做了大量的工作。程序中,首先判断如果beanDefinition.getMethodOverrides()为空也就是用户没有使用replace 或者lookup 的配置方法,那么直接使用反射的方式,简单快捷,但是如果使用了这两个特性,在直接使用反射的方式创建实例就不妥了,因为需要将这两个配置提供的功能切入进去,所以就必须要使用动态代理的方式将包含两个特性所对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例。对于拦截器的处理方法非常简单,不再详细介绍,可以仔细读一下关于AOP 的介绍,对动态代理方面的知识会有更详细地介绍。

8.2、记录创建bean 的ObjectFactory

clipboard

  • earlySingletonExposure : 从字面的意思理解就是提早曝光的单例,我们暂不定义它的学名叫什么,我们感兴趣的是有哪些条件影响这个值。
  • mbd.isSingleton():此RootBeanDefinition 代表的是否是单例。
  • this.allowCircularReferences :是否允许循环依赖,很抱歉,并没有找到在配直文件中如何配直,但是在AbstractRefreshableApplicationContext 中提供了设直函数,可以通过硬编码的方式进行设直或者可以通过自定义命名空间进行配直,其中硬编码的方式代码如下:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-circleReference.xml");
context.setAllowBeanDefinitionOverriding(false);
  • isSingletonCurrentlylnCreation(beanName):该bean 是否在创建中。在bean开始创建前会将beanName记录在属性中,在bean创建结束后,会将beanName从属性中移除。这个状态又是在哪里记录的呢?Spring对于不同scope记录位置并不一样。我们 以singleton为例,在singleton模式下记录属性的函数是DefaultSingletonBeanRegistry.java:getSingleton()中的beforeSingletonCreation(beanName)函数和afterSingletonCreation()函数。
    clipboard
8.3、属性注入

AbstractAutowireCapableBeanFactory.java

/**
 * Populate the bean instance in the given BeanWrapper with the property values
 * from the bean definition.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @param bw the BeanWrapper with bean instance
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   if (bw == null) {
      if (mbd.hasPropertyValues()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         //没有可以填充的属性
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   //给InstantiationAwareBeanPostProcessors最后一次机会哎属性设置前来改变bean
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            //是否继续填充bean?true:继续填充,false:停止填充
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               //如果处理器发出停止填充命令,则终止后续执行
               return;
            }
         }
      }
   }

   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
         //根据名称自动注入
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
         //根据类型自动注入
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }
   //后处理器已经初始化
   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   //需要依赖检查
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   if (hasInstAwareBpps || needsDepCheck) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               //对所有需要依赖检查的属性进行后处理
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
      if (needsDepCheck) {
         //依赖检查,对应depend-on属性,spring.3.0已经弃用该属性
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }

   if (pvs != null) {
      //将属性应用到bean中
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

以上逻辑概要:
①、InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation函数的应用,此函数可以控制程序是否继续进行属性填充。
②、根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中。(8.3.1、autowireByName()、详解)(8.3.2、autowireByType()、详解)
③、应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues(),对属性获取完毕填充前对属性再次处理,典型应用:RequiredAnnotationBeanPostProcessor.java中对属性的验证。
④、将所有PropertyValue中的属性填充至BeanWrapper中。(8.3.3、applyPropertyValues()、详解)

8.3.1、autowireByName(逻辑②详解)

  提取依赖的bean,并统一存入PropertyValues中

AbstractAutowireCapableBeanFactory.java

/**
 * Fill in any missing property values with references to
 * other beans in this factory if autowire is set to "byName".
 * @param beanName the name of the bean we're wiring up.
 * Useful for debugging messages; not used functionally.
 * @param mbd bean definition to update through autowiring
 * @param bw the BeanWrapper from which we can obtain information about the bean
 * @param pvs the PropertyValues to register wired objects with
 */
protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
   //寻找bw中需要依赖注入的属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      if (containsBean(propertyName)) {
         //递归初始化相关的bean
         Object bean = getBean(propertyName);
         pvs.add(propertyName, bean);
         //注册依赖
         registerDependentBean(propertyName, beanName);
         if (logger.isDebugEnabled()) {
            logger.debug("Added autowiring by name from bean name '" + beanName +
                  "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
         }
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                  "' by name: no matching bean found");
         }
      }
   }
}

  如果读者之前了解了autowire 的使用方法,相信理解这个函数的功能不会太困难,无非是在传人的参数mbd、bw 中找出已经加载的bean , 并递归实例化,进而加入到pvs 中。

8.3.2、autowireByType(逻辑②详解)

AbstractAutowireCapableBeanFactory.java

/**
 * Abstract method defining "autowire by type" (bean properties by type) behavior.
 * <p>This is like PicoContainer default, in which there must be exactly one bean
 * of the property type in the bean factory. This makes bean factories simple to
 * configure for small namespaces, but doesn't work as well as standard Spring
 * behavior for bigger applications.
 * @param beanName the name of the bean to autowire by type
 * @param mbd the merged bean definition to update through autowiring
 * @param bw the BeanWrapper from which we can obtain information about the bean
 * @param pvs the PropertyValues to register wired objects with
 */
protected void autowireByType(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }

   Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
   //寻找bw中需要依赖注入的属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      try {
         PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
         // Don't try autowiring by type for type Object: never makes sense,
         // even if it technically is a unsatisfied, non-simple property.
         if (Object.class != pd.getPropertyType()) {
            //探测指定属性的set方法
            MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
            // Do not allow eager init for type matching in case of a prioritized post-processor.
            boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
            DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
            //解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,当属性存在多个封装bean时:
            //@Autowired private List<A> aList;将会找到所有匹配A类型的bean并将其注入
            Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
            if (autowiredArgument != null) {
               pvs.add(propertyName, autowiredArgument);
            }
            for (String autowiredBeanName : autowiredBeanNames) {
               //注册依赖
               registerDependentBean(autowiredBeanName, beanName);
               if (logger.isDebugEnabled()) {
                  logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
                        propertyName + "' to bean named '" + autowiredBeanName + "'");
               }
            }
            autowiredBeanNames.clear();
         }
      }
      catch (BeansException ex) {
         throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
      }
   }
}

  实现根据名称自动匹配的第一步就是寻找bw 中需要依赖注入的属性,同样对于根据类型自动匹配的实现来讲第一步也是寻找bw 中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的bean , 其中最复杂的就是寻找类型匹配的bean 。同时, Spring 中提供了对集合的类型注入的支持,如使用注解的方式:

@Auwowired
private List<Test> tests;

  Spring 将会把所有与Test 匹配的类型找出来并注入到tests 属性中,正是由于这一因素,所以在autowireByType() 函数中,新建了局部遍历autowiredBeanNames ,用于存储所有依赖的bean ,如果只是对非集合类的属性注入来说,此属性并无用处。
clipboard

DefaultListableBeanFactory.java:doResolveDependency()

@Nullable
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      Object shortcut = descriptor.resolveShortcut(this);
      if (shortcut != null) {
         return shortcut;
      }

      Class<?> type = descriptor.getDependencyType();
      //用于spring中新增的注解@Value
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         return (descriptor.getField() != null ?
               converter.convertIfNecessary(value, type, descriptor.getField()) :
               converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
      }

      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }

      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;

      if (matchingBeans.size() > 1) {
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(type, matchingBeans);
            }
            else {
               // In case of an optional Collection/Map, silently ignore a non-unique case:
               // possibly it was meant to be an empty collection of multiple regular beans
               // (before 4.3 in particular when we didn't even look for collection beans).
               return null;
            }
         }
         instanceCandidate = matchingBeans.get(autowiredBeanName);
      }
      else {
         // We have exactly one match.
         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }
      Object result = instanceCandidate;
      if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }
      if (!ClassUtils.isAssignableValue(type, result)) {
         throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
      }
      return result;
   }
   finally {
      ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
   }
}
8.3.3、applyPropertyValues(逻辑④详解)
/**
 * Apply the given property values, resolving any runtime references
 * to other beans in this bean factory. Must use deep copy, so we
 * don't permanently modify this property.
 * @param beanName the bean name passed for better exception information
 * @param mbd the merged bean definition
 * @param bw the BeanWrapper wrapping the target object
 * @param pvs the new property values
 */
//属性填充
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
   if (pvs.isEmpty()) {
      return;
   }

   if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
      ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
   }

   MutablePropertyValues mpvs = null;
   List<PropertyValue> original;

   if (pvs instanceof MutablePropertyValues) {
      mpvs = (MutablePropertyValues) pvs;
      //如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到beanWapper中
      if (mpvs.isConverted()) {
         // Shortcut: use the pre-converted values as-is.
         try {
            bw.setPropertyValues(mpvs);
            return;
         }
         catch (BeansException ex) {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Error setting property values", ex);
         }
      }
      original = mpvs.getPropertyValueList();
   }
   else {
      //如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法。
      original = Arrays.asList(pvs.getPropertyValues());
   }

   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }
   //获取对应的解析器
   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

   // Create a deep copy, resolving any references for values.
   List<PropertyValue> deepCopy = new ArrayList<>(original.size());
   boolean resolveNecessary = false;
   //遍历属性,将属性转换为对应类的对应属性的类型
   for (PropertyValue pv : original) {
      if (pv.isConverted()) {
         deepCopy.add(pv);
      }
      else {
         String propertyName = pv.getName();
         Object originalValue = pv.getValue();
         Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
         Object convertedValue = resolvedValue;
         boolean convertible = bw.isWritableProperty(propertyName) &&
               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
         if (convertible) {
            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
         }
         // Possibly store converted value in merged bean definition,
         // in order to avoid re-conversion for every created bean instance.
         if (resolvedValue == originalValue) {
            if (convertible) {
               pv.setConvertedValue(convertedValue);
            }
            deepCopy.add(pv);
         }
         else if (convertible && originalValue instanceof TypedStringValue &&
               !((TypedStringValue) originalValue).isDynamic() &&
               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
            pv.setConvertedValue(convertedValue);
            deepCopy.add(pv);
         }
         else {
            resolveNecessary = true;
            deepCopy.add(new PropertyValue(pv, convertedValue));
         }
      }
   }
   if (mpvs != null && !resolveNecessary) {
      mpvs.setConverted();
   }

   // Set our (possibly massaged) deep copy.
   try {
      bw.setPropertyValues(new MutablePropertyValues(deepCopy));
   }
   catch (BeansException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
   }
}

2.4、初始化Bean

posted @ 2025-12-26 12:32  Carey_ccl  阅读(6)  评论(0)    收藏  举报