1. 揭秘Spring类型转换 - 框架设计的基石(下)

简介: 1. 揭秘Spring类型转换 - 框架设计的基石(下)

新一代转换服务接口:ConversionService


从上一小节我们知道,新的这套接口中,Converter、ConverterFactory、GenericConverter它们三都着力于完成类型转换。对于使用者而言,如果做个类型转换需要了解到这三套体系无疑成本太高,因此就有了ConversionService用于整合它们三,统一化接口操作。


此接口也是Spring 3.0新增,用于统一化 底层类型转换实现的差异,对外提供统一服务,所以它也被称作类型转换的门面接口,从接口名称xxxService也能看出来其设计思路。它主要有两大实现:


  1. GenericConversionService:提供模版实现,如转换器的注册、删除、匹配查找等,但并不内置转换器实现
  2. DefaultConversionService:继承自GenericConversionService。在它基础上默认注册了非常多的内建的转换器实现,从而能够实现绝大部分的类型转换需求


ConversionService转换服务它贯穿于Spring上下文ApplicationContext的多项功能,包括但不限于:BeanWrapper处理Bean属性、DataBinder数据绑定、PropertySource外部化属性处理等等。因此想要进一步深入了解的话,ConversionService是你绕不过去的坎。


说明:很多小伙伴问WebConversionService是什么场景下使用?我说:它并非Spirng Framework的API,而属于Spring Boot提供的增强,且起始于2.x版本,这点需引起注意


这块内容将在本系列后面具体篇章中得到专题详解,敬请关注。


类型转换整合格式化器Formatter


Spring 3.0还新增了一个Formatter<T>接口,作用为:将Object格式化为类型T。从语义上理解它也具有类型转换(数据转换的作用),相较于Converter<S,T>它强调的是格式化,因此一般用于时间/日期、数字(小数、分数、科学计数法等等)、货币等场景,举例它的实现:


  1. DurationFormatter:字符串和Duration类型的互转
  2. CurrencyUnitFormatter:字符串和javax.money.CurrencyUnit货币类型互转
  3. DateFormatter:字符串和java.util.Date类型互转。这个就使用得太多了,它默认支持什么格式?支持哪些输出方式,这将在后文详细描述


为了和类型转换服务ConversionService完成整合,对外只提供统一的API。Spring提供了FormattingConversionService专门用于整合Converter和Formatter,从而使得两者具有一致的编程体验,对开发者更加友好。


这块内容将在本系列后面具体篇章中得到专题详解,敬请关注。


类型转换底层接口TypeConvert


定义类型转换方法的接口,它在Spring 2.0就已经存在。在还没有ConversionService之前,它的类型转换动作均委托给已注册的PropertyEditor来完成。但自3.0之后,这个转换动作可能被PropertyEditor来做,也可能交给ConversionService处理。


它一共提供三个重载方法:


// @since 2.0
public interface TypeConverter {
  // value:待转换的source源数据
  // requiredType:目标类型targetType
  // methodParam:转换的目标方法参数,主要为了分析泛型类型,可能为null
  // field:目标的反射字段,为了泛型,可能为null
  <T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException;
  <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException;
  <T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) throws TypeMismatchException;
}


它是Spring内部使用类型转换的入口,最终委托给PropertyEditor或者注册到ConversionService里的转换器去完成。它的主要实现有:


  • TypeConverterSupport:@since 3.2。继承自PropertyEditorRegistrySupport,它主要是为子类BeanWrapperImpl提供功能支撑。作用有如下两方面:
  1. 提供对默认编辑器(支持JDK内置类型的转换如:Charset、Class、Class[]、Properties、Collection等等)和自定义编辑器的管理(PropertyEditorRegistry#registerCustomEditor)
  2. 提供get/set方法,把ConversionService管理上(可选依赖,可为null)
  • 数据绑定相关:因为数据绑定强依赖于类型转换,因此数据绑定涉及到的属性访问操作将会依赖于此组件,不管是直接访问属性的DirectFieldAccessor还是功能更强大的BeanWrapperImpl均是如此


总的来说,TypeConverter能把类型的各种实现、API收口于此,Spring把类型转换的能力都转嫁到TypeConverter这个API里面去了。虽然方便了使用,但其内部实现原理稍显复杂,同样的这块内容将在本系列后面具体篇章中得到专题详解,敬请关注。


Spring Boot使用增强


在传统Spring Framework场景下,若想使用ConversionService还得手动档去配置,这对于不太了解其运行机制的同学无疑是有使用门槛的。而在Spring Boot场景下这一切都会变得简单许多,可谓使用起来愈发方便了。


另外,Spring Boot在内建转换器的基础上额外扩展了不少实用转换器,形如:


  • StringToFileConverter:String -> File
  • NumberToDurationConverter:
  • DelimitedStringToCollectionConverter:


✍总结


基于配置来控制程序运行总比你修改程序代码来得更优雅、更富弹性,但这是需要依赖于数据绑定、数据校验等功能的,而它们又依赖于类型转换。


虽说几乎所有的框架都会有类型转换的功能模块,但Spring的可能是最为通用、最为经典的存在。因此本系列专题讲解Spring Framework的类型转换,旨在能够帮你你撬开通往跃升的大门,节节攀高。

相关文章
|
8月前
|
XML 存储 设计模式
Spring高手之路11——BeanDefinition解密:构建和管理Spring Beans的基石
本文对BeanDefinition进行全面深入的探讨,涵盖BeanDefinition的接口方法、主要信息、类型以及生成过程等方面内容。旨在帮助读者全面理解BeanDefinition的各方面知识,并能够熟练应用。文章通俗易懂,具有很强的指导意义。
65 0
Spring高手之路11——BeanDefinition解密:构建和管理Spring Beans的基石
|
10月前
|
前端开发 Java Spring
《Spring MVC》 第六章 MVC类型转换器、格式化器
《Spring MVC》 第六章 MVC类型转换器、格式化器
145 0
|
前端开发 Java Spring
Spring MVC框架:第十三章:类型转换
Spring MVC框架:第十三章:类型转换
|
XML Java 数据格式
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)(下)
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)(下)
200 0
|
XML 前端开发 Java
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)(中)
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)(中)
180 0
|
XML Java API
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)(上)
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)
177 0
最新最全面的Spring详解(三)——Resources,验证、数据绑定和类型转换与Spring表达式语言(SpEL)(上)
|
XML 存储 Java
Spring 核心特性之类型转换(PropertyEditor、ConversionService)
前言 与数据绑定一样,类型转换同样是 Spring 的核心特性之一,Spring 最初的配置信息主要以 XML 的形式存在,这就要求 Spring 将字符串形式的配置转换为具体的 Java 类型,经过多个版本的演进,Spring 中的类型转换功能愈发成熟。
224 0
Spring 核心特性之类型转换(PropertyEditor、ConversionService)
|
Java uml Spring
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(3)
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(3)
84 0
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(3)
|
Java API uml
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(2)
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(2)
222 0
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(2)
|
XML Java 数据格式
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(1)
BeanWrapper是Spring中一个很重要的接口,Spring在通过配置信息创建对象时,第一步首先就是创建一个BeanWrapper。这篇文章我们就分析下这个接口,本文内容主要对应官网中的3.3及3.4小结
177 0
Spring官网阅读(十四)Spring中的BeanWrapper及类型转换(1)