
1Spring中的类型转换,主要用在两种场景
这里着重讲解下MVC中的使用方法以及Conversion实现原理
2本文主要梳理下Spring Mvc中Conversion的机制
先看下Conversion在具体应用中的体现:
http://localhost:8080/spring-mvc-showcase/convert/collection?values=1,2,3,4,5
这个url是我们的http请求,其中参数values=1,2,3,4,5是一个逗号分隔的字符串,在web server后端的Controller中,我们可以如何接收呢?
这是接收请求的方法,可以看到,是用CollectionInteger来接收values参数的,到这里已经变更整形的集合了.
没错,这就是在绑定参数的过程中用到了ConversionService,上边这个具体是用到了Spring内置的StringToCollectionConverter
看注释可知道,这是一个专门转换用逗号分隔字符串为集合的converter
3整个Spring中的Conversion机制有几个关键的类或接口:
下图是Spring内置的Converter:

这些是Spring内置的与Collection转换相关的converter

整个Conversion机制还是比较复杂的,所以Spring提供了统一的facade门面,ConversionService接口,对外统一了几个转换相关的方法,屏蔽了具体的转换逻辑。

在转换服务内部,ConverRegistry是提供了所有Converter的注册管理功能

DefaultConversionService的继承结构图如下:

它整合了ConversionService和ConverRegistry接口的功能,能管理众多Converter并提供conversion常用操作,是整个Convertsion的核心类,所有的转换组件基本都是delegate给这个类来实现具体的转换功能
ConversionServiceFactoryBean是作为外部调用方直接使用的类,采用工厂的模式生成ConversionService,这也符合Spring的一贯作风,比较重且复杂的类构造起来一般采用工厂模式,其实它生成的对象就是DefaultConversionService,它同时提供了设置用户算定义Converter的功能,通过setConverter方法加入到ConverterRegistry中。

FormattingConversionServiceFactoryBean与ConversionServiceFactoryBean结构类似且更强大,是SpringMVC默认的ConverterService,它又多了setFormatter的功能,能够以解析格式化字段的方式来提供转换功能。
4在Spring mvc中这些组件是如何组织工作的呢?
在使用xml配置Spring mvc的app来说一般是这样的:


上边是通过mvc:annotation/来配置mvc相关基础设施,其中的conversion-service属性就是用来指定用户自定义ConversionService的。
在Spring的xml中各种标签的解析,是各种***NamespaceHandler来完成的,比方说mvc标签的解析类就是MvcNamespaceHandler

对于mvc:annotation-driven标签的解析是通过AnnotationDrivenBeanDefinitionParser类来完成的。
getConversionService方法是具体解析ConversionService的方法:

这里可以看到,如果我们配置了自定义ConversionService的话就会被Spring容器使用,否则会给默认装配一个FormattingConversionServiceFactoryBean
至此,在Spring mvc的容器中就可以用这个bean来获取ConversionService,来提供转换服务。

SpringAutowired
一个有用的公众号