spring-core组件详解——类型转换系统

原创
2016/04/29 18:16
阅读数 2.9K

类型转换系统,顾名思义,就是负责spring框架中的对象类型转换工作。

类型转换系统体系图如下:

整个类型转换系统包括两个核心接口(ConversionService和ConverterRegistry)和一个核心实现类(GenericConversionService)。

  1. ConversionService(转换服务)接口定义了类型转换系统具有的核心功能,包括判断当前服务是否能够完成原始类型(sourceType)到目标类型(targetType)的转换,以及把原始对象(sourceObject)转换成目标类型对象。

接口如下:

    2.ConverterRegistry(转换器注册表)接口,使得类型转换系统可以管理(添加或删除)内部的转换器。

所有的对象类型转换,实际都是由转换系统内部的各个转换器完成转换的。

接口如下:

    转换器注册表可以管理3种类型的转换器(关于转换器,稍后详解。。。):

  • Converter<S,T>:把原始类型S,转换成目标类型T

  • GenericConverter:通用转换器

  • ConverterFactory<S,R>:转换器工厂,通过它可以获取Converter<S,T>对象(T extends R)。


以上两个接口都只是类型转换系统的部分功能,因此使用ConfigurableConversionService接口类整合这两部分功能。

ConfigurableConversionService接口只起整合作用,并没有定义新的功能。


GenericConversionService(通用类型转换服务),是整个类型转换系统的完整实现。它作为一个容器,可以管理转换器,同时可以调用这些转换器进行类型转换。但是,此类只是一个空的容器,内部还没有任何转换器。


DefaultConversionService(默认的类型转换服务):此类是默认的类型转换系统,它继承自GenericConversionService类,但是没有添加任何新的功能,只是在构造方法中调用addDefaultConverters向自身添加了许多默认的转换器。

部分代码如下:

public class DefaultConversionService extends GenericConversionService {

	
	public DefaultConversionService() {
		// 向当前对象中添加默认的转换器添加默认的转换器
		addDefaultConverters(this);
	}

	public static void addDefaultConverters(ConverterRegistry converterRegistry) {
		// 
		addScalarConverters(converterRegistry);
		// 
		addCollectionConverters(converterRegistry);
		//
		converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
		//
		if (jsr310Available) {
			Jsr310ConverterRegistrar.registerZoneIdConverters(converterRegistry);
		}
		//
		converterRegistry.addConverter(new ObjectToObjectConverter());
		//
		converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
		//
		converterRegistry.addConverter(new FallbackObjectToStringConverter());
		if (javaUtilOptionalClassAvailable) {
			converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
		}
	}

}


到这里,整个类型转换系统已经可以正常运行了。在基于spring框架的应用中,只需要

ConversionService conversionService = new DefaultConversionService();

即可以使用这个系统进行类型转换了。


下面来说说转换器。

从GenericConversionService类的源码中可以看到,converters保存了所有的转换器(Converters类是GenericConversionService的成员内部类)。

/**
* GenericConversionService
*/
// 当前变量保存了所有的转换器
private final Converters converters = new Converters();


刚刚上文已经提到,共有3种类型的转换器:

  • Converter<S,T>:把原始类型S,转换成目标类型T

  • GenericConverter:通用转换器

  • ConverterFactory<S,R>:转换器工厂,通过它可以获取Converter<S,T>对象(T extends R)。

但是,添加到converters中的转换器都是GenericConverter类型(或者说是ConditionalGenericConverter类型)的转换器,这一点可以从所有addConverter方法观察到。


那么Converter<S,T>和ConverterFactory<S,R>与GenericConverter之间又有什么关系呢?


从GenericConversionService源码中可以看到,spring框架通过适配器模式,将Converter<S,T>接口和ConverterFactory<S,R>接口都转换成了GenericConverter类型(实际类型为ConditionalGenericConverter)。这一过程是由GenericConversionService的成员内部类ConverterAdapter完成的。


GenericConverter通用转换器体系图如下:

1.GenericConverter:通用转换器,定义了2种功能,一是获取可转换的类型组合的集合,一是根据原始类型和目标类型对原始对象进行类型转换。

关于TypeDiscriptor类型描述器,稍后解释。

接口中的成员内部类ConvertiblePair,描述了一个原始类型到目标类型的组合。

public static final class ConvertiblePair {
	// 原始类型
	private final Class<?> sourceType;
	// 目标类型
	private final Class<?> targetType;
	
}

2.ConditionalConverter:有条件的转换器,此接口定义了一个功能,就是判断当前转换器是否可以完成原始类型到目标类型的转换。

3.ConditionalGenericConverter:有条件的通用转换器,整合了上述的连个接口的功能。


接下来就是org.springframework.core.convert.support包中,各种转换器的实现了。一般情况下,转换器都需要实现ConditionalGenericConverter接口,只有极少数转换器只实现了GenericConverter接口。


最后,附上DefaultGenericConversionService可转换的所有ConvertiblePai列表:

格式:sourceType-->targetType

Number-->Number

String-->Number

Number-->String

String-->Character

Character-->String

Number-->Character

Character-->Number

String-->Boolean

Boolean-->String

String-->Enum

Enum-->String

String-->Locale

Locale-->String

String-->Properties

Properties-->String

String-->UUID

UUID-->String

Object[]-->Collection

Collection-->Object[]

Object[]-->Object[]

Collection-->Collection

Map-->Map

Object[]-->String

String-->Object[]

Object[]-->Object

Object-->Object[]

Collection-->String

String-->Collection

Collection-->Object

Object-->Collection

ByteBuffer-->Object

ByteBuffer-->byte[]

byte[]-->ByteBuffer

Object-->ByteBuffer

ZoneId-->TimeZone

ZonedDateTime-->Calendar

Object-->Object

Object-->String

Object-->Optional


展开阅读全文
加载中

作者的其它热门文章

打赏
2
32 收藏
分享
打赏
0 评论
32 收藏
2
分享
返回顶部
顶部