7.盤點springmvc的經常使用接口之Converter(下篇)

7.盤點springmvc的經常使用接口之Converter(下篇)###

前兩章介紹了ConverterConverterFactory以及衍生出來的GenericConverterConditionalGenericConverter,最後附錄羅列了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,它實現了ConversionServiceConverterRegistry接口,可是它不能直接拿來使用。由於不能經過相似下面的配置往裏面添加咱們本身的轉換器。翻譯

<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>

友情連接

盤點springmvc的經常使用接口目錄

相關文章
相關標籤/搜索