前兩章介紹了Converter
、ConverterFactory
以及衍生出來的GenericConverter
、ConditionalGenericConverter
,最後附錄羅列了Spring自帶的各類轉換器。這麼多的轉換器,咱們開發者可不想在要使用轉換器時還本身來查找轉換器使用。因此爲了統一調用Converter
進行類型轉換,Spring友好地爲咱們提供了一個org.springframework.core.convert.ConversionService
接口。咱們靠猜都知道查詢一個轉換器,確定是經過原類型和目標類型來查的,並且在查到轉換器後咱們會經過convert
方法來執行轉換過程。java
那麼這個ConversionService
的接口看起來應該是這樣子:spring
public interface ConversionService { boolean canConvert(Class<?> sourceType, Class<?> targetType); boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType); <T> T convert(Object source, Class<T> targetType); Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
一對canConvert
來判斷是否匹配原類型和目標類型,設計模式
一對convert
執行轉換過程。其中TypeDescriptor
是類型的描述,裏面包含該種類型的值、實際類型等等信息。mvc
ConversionService
接口它還有一個好基友org.springframework.core.convert.converter.ConverterRegistry
,通常這兩個接口都是同時出現,ConverterRegistry
的做用是對轉換器的管理,作一個統一的註冊工做。它包含一系列的增刪轉換器的操做。接口以下:ide
public interface ConverterRegistry { void addConverter(Converter<?, ?> converter); void addConverter(Class<?> sourceType, Class<?> targetType, Converter<?, ?> converter); void addConverter(GenericConverter converter); void addConverterFactory(ConverterFactory<?, ?> converterFactory); void removeConvertible(Class<?> sourceType, Class<?> targetType);
方法名字比較直白就不翻譯了。.net
對於衆多轉換器的註冊管理,查詢執行轉換工做就給咱們這兩個接口未免實現起來也有點困難。因此Spring已經給咱們提供了一個實現org.springframework.core.convert.support.GenericConversionService
,它實現了ConversionService
和ConverterRegistry
接口,可是它不能直接拿來使用。由於不能經過相似下面的配置往裏面添加咱們本身的轉換器。翻譯
<mvc:annotation-driven conversion-service="myConversionService"/> <bean id="myConversionService" class="com.demo.mvc.component.MyConversionService"> <property name="customConverters"> <set> <bean class="com.demo.mvc.component.TelephoneConverter"/> </set> </property> </bean>
因此這個地方咱們能夠用到一款經典的設計模式,那就是「裝飾模式」,在GenericConversionService
上套上咱們本身的裝飾器。設計
package com.demo.mvc.component; import java.util.Set; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.support.GenericConversionService; import lombok.Getter; import lombok.Setter; public class MyConversionService implements ConversionService { @Autowired private GenericConversionService conversionService; @Getter @Setter private Set<?> customConverters; @PostConstruct public void afterInjectCustomConverters() { if (customConverters != null) { for (Object converter : customConverters) { if (converter instanceof Converter<?, ?>) { conversionService.addConverter((Converter<?, ?>) converter); } else if (converter instanceof ConverterFactory<?, ?>) { conversionService.addConverterFactory((ConverterFactory<?, ?>) converter); } else if (converter instanceof GenericConverter) { conversionService.addConverter((GenericConverter) converter); } } } } @Override public boolean canConvert(Class<?> sourceType, Class<?> targetType) { return conversionService.canConvert(sourceType, targetType); } @Override public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) { return conversionService.canConvert(sourceType, targetType); } @Override public <T> T convert(Object source, Class<T> targetType) { return conversionService.convert(source, targetType); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { return conversionService.convert(source, sourceType, targetType); } }
經過customConverters
集合能夠把咱們自定義的轉換器設置進來,再調用afterInjectCustomConverters
方法設置到GenericConversionService
中,以後的其它操做都是調用原來的GenericConversionService
的方法。code
除了以上這種本身實現的裝飾器外,Spring已經爲咱們提供了一個既可使用GenericConversionService
又能夠添加本身的轉換器的類,那就是org.springframework.context.support.ConversionServiceFactoryBean
。這個類提供了一個converters
屬性讓咱們設置本身的轉換器。在對象初始化完成以後它會new一個GenericConversionService
對象,並往GenericConversionService
中註冊converters
屬性指定的Converter
和Spring自身已經實現了的默認Converter
,以後每次返回的都是這個GenericConversionService
對象。註冊時,咱們能夠這樣配置:component
<mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.demo.mvc.component.TelephoneConverter"/> </set> </property> </bean>
GenericConversionService
的子類還有FormattingConversionService
,這個類既能夠轉換類型又能夠格式化。它也有一個FactoryBean
來輔助註冊:
<mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.demo.mvc.component.TelephoneConverter"/> </set> </property> </bean>
友情連接