BeanWrapper(三)

简介: 其实这篇文章只是单纯的去了解关于 PropertyEditor 和 ConversionServer 的知识、并没有从源码详细说 Spring 怎么怎么去使用它们、这个可能放到以后的文章。这篇文章单纯是补全这个主题的基础知识、为后面继续看 Spring 的代码进行铺垫。

TypeConverterDelegate


再回到我们上面的 TypeConverterSupport 提及到的 TypeConverterDelegate

class TypeConverterDelegate {
  private final PropertyEditorRegistrySupport propertyEditorRegistry;
  @Nullable
  private final Object targetObject;
  public <T> T convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue,
      @Nullable Class<T> requiredType, @Nullable TypeDescriptor typeDescriptor) throws IllegalArgumentException {
    // 查看是否为当前这个类型配置了定制的PropertyEditor
    PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
    ConversionFailedException conversionAttemptEx = null;
    // 获取当前容器中的类型转换业务类
    ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
        // 在这里可以看出,Spring底层在进行类型转换时有两套机制
        // 1.首选的是采用PropertyEditor
        // 2.在没有配置PropertyEditor的情况下,会采用conversionService
    if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) {
      TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
      if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
        try {
                    // 通过conversionService进行类型转换
          return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
        }
        catch (ConversionFailedException ex) {
          // fallback to default conversion logic below
          conversionAttemptEx = ex;
        }
      }
    }
    Object convertedValue = newValue;
    // 配置了定制的属性编辑器,采用PropertyEditor进行属性转换
    if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
      if (typeDescriptor != null && requiredType != null && Collection.class.isAssignableFrom(requiredType) &&
          convertedValue instanceof String) {
        TypeDescriptor elementTypeDesc = typeDescriptor.getElementTypeDescriptor();
        if (elementTypeDesc != null) {
          Class<?> elementType = elementTypeDesc.getType();
          if (Class.class == elementType || Enum.class.isAssignableFrom(elementType)) {
            convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
          }
        }
      }
      if (editor == null) {
                // 没有配置定制的属性编辑器,采用默认的属性编辑器
        editor = findDefaultEditor(requiredType);
      }
            // 采用属性编辑器进行转换,需要注意的是,默认情况下PropertyEditor只会对String类型的值进行类型转换
      convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
    }
        // .....
    return (T) convertedValue;
  }
}
复制代码

从上面的代码中我们可以知道,Spring 在实现类型转换时,有两套机制,第一套机制依赖于 PropertyEditor ,第二套机制依赖于 ConversionService 。关于属性编辑器 PropertyEditor 我们之前已经介绍过了,主要进行的是 String 到 Object 的转换,正因为如此,属性编辑器进行类型转换有很大的局限性,所以 Spring 又推出了一套 ConversionService 的体系。


ConversionService

Converter

@FunctionalInterface
public interface Converter<S, T> {
  // 从 S 转换到 T 
   @Nullable
   T convert(S source);
}
复制代码

网络异常,图片无法展示
|

Spring 提供的从 S 类型转换到 T 类型的转换器


ConverterFactory

为了方便能够将 S 转为一系列的 T 类型。比如说 String 转为各种 Enum 或者 Number

网络异常,图片无法展示
|


ConverterRegistry

转换器的注册器


ConversionService

相当于 Registrar 的功能。线程安全的、其实可以从 Converter 的定义可以看出、Converter 是无状态的而不像 PropertyEditor


ApplicationConversionService

在 SpringApplication 的 run 方法的 prepareEnvironment 的 configureEnvironment 中创建了 ApplicationConversionService 并且添加了各种常见的转换器。

网络异常,图片无法展示
|

网络异常,图片无法展示
|


最后


其实这篇文章只是单纯的去了解关于 PropertyEditor 和 ConversionServer 的知识、并没有从源码详细说 Spring 怎么怎么去使用它们、这个可能放到以后的文章。这篇文章单纯是补全这个主题的基础知识、为后面继续看 Spring 的代码进行铺垫。

目录
相关文章
|
6月前
|
XML Java 数据库连接
FactoryBean的使用~
FactoryBean的使用~
|
8月前
|
Java 开发者 Spring
BeanFactory和FactoryBean
BeanFactory和FactoryBean
63 0
|
Java Spring 容器
|
安全 Java Spring
BeanWrapper(一)
其实这篇文章只是单纯的去了解关于 PropertyEditor 和 ConversionServer 的知识、并没有从源码详细说 Spring 怎么怎么去使用它们、这个可能放到以后的文章。这篇文章单纯是补全这个主题的基础知识、为后面继续看 Spring 的代码进行铺垫。
114 0
|
安全 Java Spring
BeanWrapper(二)
其实这篇文章只是单纯的去了解关于 PropertyEditor 和 ConversionServer 的知识、并没有从源码详细说 Spring 怎么怎么去使用它们、这个可能放到以后的文章。这篇文章单纯是补全这个主题的基础知识、为后面继续看 Spring 的代码进行铺垫。
180 0
|
缓存 Java API
3. 搞定收工,PropertyEditor就到这(上)
3. 搞定收工,PropertyEditor就到这(上)
3. 搞定收工,PropertyEditor就到这(上)
|
搜索推荐 Java API
3. 搞定收工,PropertyEditor就到这(下)
3. 搞定收工,PropertyEditor就到这(下)
3. 搞定收工,PropertyEditor就到这(下)
|
XML Java 数据格式
【Spring源码解析】SpringIOC(1)—— Bean与BeanDefinition
全局视角看核心接口和类 Bean与BeanDefinition BeanDefinition是Bean的定义 容器初始化主要做的事情(主要脉络) BeanDefinition源码
【Spring源码解析】SpringIOC(1)—— Bean与BeanDefinition
|
XML Java Maven
BeanFactory 和 FactoryBean 的理解
大家好,我是本周的值班编辑 江南一点雨 ,本周将由我为大家排版并送出技术干货,大家可以在公众号后台回复“springboot”,获取最新版 Spring Boot2.1.6 视频教程试看。 我们或多或少都会经历过若干个面试,而每每问到 Spring 的时候都少不了IOC容器的影子,那么这个 IOC 容器是什么呢? 本篇文章就来了解一下 BeanFactory 和 FactoryBean
|
容器
FactoryBean 和BeanFactory
FactoryBean 和BeanFactory
103 0