spring源码学习笔记之bean创建流程(九)

250 阅读7分钟

前面的那些处理都是前期准备工作,接下来的 finishBeanFactoryInitialization方法正式进入bean的创建流程。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   // 为上下文初始化类型转换器
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   // 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   // 禁止使用临时类加载器进行类型匹配
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   // 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   // 实例化剩下的单例对象
   beanFactory.preInstantiateSingletons();
}
  • 设置转换器 ConversionService ConversionService 中会设置各种类型的转换器
public static void addDefaultConverters(ConverterRegistry converterRegistry) {
   addScalarConverters(converterRegistry);
   addCollectionConverters(converterRegistry);

   converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
   converterRegistry.addConverter(new StringToTimeZoneConverter());
   converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
   converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());

   converterRegistry.addConverter(new ObjectToObjectConverter());
   converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
   converterRegistry.addConverter(new FallbackObjectToStringConverter());
   converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}
  • 转换器类型
  1. Converter 将S类型转换成T类型
@FunctionalInterface
public interface Converter<S, T> {

   /**
    * 将S类型转换成T类型
    *
    * Convert the source object of type {@code S} to target type {@code T}.
    * @param source the source object to convert, which must be an instance of {@code S} (never {@code null})
    * @return the converted object, which must be an instance of {@code T} (potentially {@code null})
    * @throws IllegalArgumentException if the source cannot be converted to the desired target type
    */
   @Nullable
   T convert(S source);

}
  1. GenericConverter 用于两种或者更多种类型之间转换的通用转换器接口
/**
 *  转换源对象到目标类型的描述
 *
 * Convert the source object to the targetType described by the {@code TypeDescriptor}.
 * @param source the source object to convert (may be {@code null})
 * @param sourceType the type descriptor of the field we are converting from
 * @param targetType the type descriptor of the field we are converting to
 * @return the converted object
 */
@Nullable
Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
  1. ConverterFactory converter转换器的工厂类,用来获取对应的转换器
public interface ConverterFactory<S, R> {

   /**
    * 获取转换器
    *
    * Get the converter to convert from S to target type T, where T is also an instance of R.
    * @param <T> the target type
    * @param targetType the target type to convert to
    * @return a converter from S to T
    */
   <T extends R> Converter<S, T> getConverter(Class<T> targetType);

}

想要自己添加转换器可以参照官方文档:

image.png

  • 合并父类BeanDefinition操作 getMergedBeanDefinition作用:在实例化之前,要把所有的基础的beanDefinition对象转换成 RootBeanDefinition对象进行缓存,后续在需要马上要实例化的时候,直接获取定义信息,而定义信息中如果包含父类,那么必须要先创建父类才有子类。
// 合并父类BeanDefinition
   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

   // 同步:使用从bean名称映射到合并的RootBeanDefinition集合进行加锁
   synchronized (this.mergedBeanDefinitions) {
      // 用于存储bd的MergedBeanDefinition
      RootBeanDefinition mbd = null;
      //该变量表示从bean名称映射到合并的RootBeanDefinition集合中取到的mbd且该mbd需要重新合并定义
      RootBeanDefinition previous = null;

      // Check with full lock now in order to enforce the same merged instance.
      // 立即检查完全锁定,以强制执行相同的合并实例,如果没有包含bean定义
      if (containingBd == null) {
         // 从bean名称映射到合并的RootBeanDefinition集合中获取beanName对应的BeanDefinition作为mbd
         mbd = this.mergedBeanDefinitions.get(beanName);
      }

      // 如果mbd为null或者mdb需要重新合并定义
      if (mbd == null || mbd.stale) {
         // 将mdn作为previous
         previous = mbd;
         // 如果获取不到原始BeanDefinition的父Bean名
         if (bd.getParentName() == null) {
            // Use copy of given root bean definition.
            // 使用给定的RootBeanDefinition的副本,如果原始BeanDefinition是RootBeanDefinition对象
            if (bd instanceof RootBeanDefinition) {
               // 克隆一份bd的Bean定义赋值给mdb
               mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            }
            else {
               // 创建一个新的RootBeanDefinition作为bd的深层副本并赋值给mbd
               mbd = new RootBeanDefinition(bd);
            }
         }
         else {
            // Child bean definition: needs to be merged with parent.
            // 子bean定义:需要与父bean合并,定义一个父级BeanDefinition变量
            BeanDefinition pbd;
            try {
               // 获取bd的父级Bean对应的最终别名
               String parentBeanName = transformedBeanName(bd.getParentName());
               // 如果当前bean名不等于父级bean名
               if (!beanName.equals(parentBeanName)) {
                  // 获取parentBeanName的"合并的"BeanDefinition赋值给pdb
                  pbd = getMergedBeanDefinition(parentBeanName);
               }
               // 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
               // 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义
               else {
                  BeanFactory parent = getParentBeanFactory();
                  // 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
                  if (parent instanceof ConfigurableBeanFactory) {
                     // 使用父工厂获取parentBeanName对应的合并BeanDefinition赋值给pdb
                     pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                  }
                  else {
                     // 如果父工厂不是ConfigurableBeanFactory,抛出没有此类bean定义异常,父级bean名为parentBeanName等于名为beanName的bean名;
                     // 没有AbstractBeanFactory父级无法解决
                     throw new NoSuchBeanDefinitionException(parentBeanName,
                           "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                           "': cannot be resolved without a ConfigurableBeanFactory parent");
                  }
               }
            }
            catch (NoSuchBeanDefinitionException ex) {
               throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                     "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
            }
            // Deep copy with overridden values.
            // 使用父定义pbd构建一个新的RootBeanDefinition对象
            mbd = new RootBeanDefinition(pbd);
            // 使用原始bd定义信息覆盖父级的定义信息:
            // 1. 如果在给定的bean定义中指定,则将覆盖beanClass
            // 2. 将始终从给定的bean定义中获取abstract,scope,lazyInit,autowireMode,
            //           dependencyCheck和dependsOn
            // 3. 将给定bean定义中ConstructorArgumentValues,propertyValues,
            //           methodOverrides 添加到现有的bean定义中
            // 4. 如果在给定的bean定义中指定,将覆盖factoryBeanName,factoryMethodName,
            //        initMethodName,和destroyMethodName
            mbd.overrideFrom(bd);
         }

         // Set default singleton scope, if not configured before.
         // 设置默认的单例作用域(如果之前未配置),如果mbd之前没有配置过作用域
         if (!StringUtils.hasLength(mbd.getScope())) {
            // 设置mbd的作用域为单例
            mbd.setScope(SCOPE_SINGLETON);
         }

         // A bean contained in a non-singleton bean cannot be a singleton itself.
         // Let's correct this on the fly here, since this might be the result of
         // parent-child merging for the outer bean, in which case the original inner bean
         // definition will not have inherited the merged outer bean's singleton status.
         // 非单例bean中包含的bean本身不能是单例。
         // 让我们在此即时进行更正,因为这可能是外部bean的父子合并的结果,在这种情况下,
         // 原始内部bean定义将不会继承合并的外部bean的单例状态。
         // 如果有传包含bean定义且包含bean定义不是单例但mbd又是单例
         if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
            // 让mbd的作用域设置为跟containingBd的作用域一样
            mbd.setScope(containingBd.getScope());
         }

         // Cache the merged bean definition for the time being
         // (it might still get re-merged later on in order to pick up metadata changes)
         // 暂时缓存合并的bean定义(稍后可能仍会重新合并以获取元数据更正),如果没有传入包含bean定义 且 当前工厂是同意缓存bean元数据
         if (containingBd == null && isCacheBeanMetadata()) {
            //将beanName和mbd的关系添加到 从bean名称映射到合并的RootBeanDefinition集合中
            this.mergedBeanDefinitions.put(beanName, mbd);
         }
      }
      // 如果存在上一个从bean名称映射到合并的RootBeanDefinition集合中取出的mbd
      // 且该mbd需要重新合并定义
      if (previous != null) {
         // 拿previous来对mdb进行重新合并定义:
         // 1. 设置mbd的目标类型为previous的目标类型
         // 2. 设置mbd的工厂bean标记为previous的工厂bean标记
         // 3. 设置mbd的用于缓存给定bean定义的确定的Class为previous的用于缓存给定bean定义的确定的Class
         // 4. 设置mbd的工厂方法返回类型为previous的工厂方法返回类型
         // 5. 设置mbd的用于缓存用于自省的唯一工厂方法候选为previous的用于缓存用于自省的唯一工厂方法候选
         copyRelevantMergedBeanDefinitionCaches(previous, mbd);
      }
      // 返回MergedBeanDefinition
      return mbd;
   }
}
  • BeanFactory 和 FactoryBean 在创建对象的时候会有一个 isFactoryBean判断,判断是否实现了FactoryBean接口。BeanFactory 和 FactoryBean都是对象工厂,用来创建对象
    区别:
    1. BeanFactory:BeanFactory接口,必须严格遵守 springbean 的生命周期接口,从实例化到初始化,到invokeAwareMethod、invokeInitMethodr、beforef、after
    2. FactoryBean: 不需要遵循此创建顺序,通过getObject方法直接返回对象。
      当使用FactoryBean接口来创建对象的时候,我们一共创建了两个对象,一个是实现了 FactoryBean接口的子类对象,一个是通过getObject方法返回的对象。两个对象都由spring来管理,但要注意的是,实现了FactoryBean接口的对象在一级缓存,但调用getObject方法返回的对象在factoryBeanObjectCache。