Converter使用及其原理

在Spring MVC开发中,我们可以很方便的使用Converter来实现对请求参数的处理,比如字符串去空,日期格式化等。
配置文件中对Converter的引用:

    <bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.xxx.common.converter.StringTrimConverter" />
                <bean class="com.xxx.common.converter.DateConverter" />
                <bean class="com.xxx.common.converter.DatetimeConverter" />
            list>
        property>
    bean>
<mvc:annotation-driven conversion-service="conversionService">

如上代码,我们配置了三种类型的Converter。
以字符串去空为例,

import org.springframework.core.convert.converter.Converter;
/**
 * 去除前后空格
 * @author 
 *
 */
public class StringTrimConverter implements Converter<String, String> {
    public String convert(String source) {
        //如果源字符串不为空则进行转换
        if(source != null){
            //去除源字符串前后空格
            source = source.trim();
            if(source.equals("")){ 
                source = null;
            }
        }
        return source;
    }
}

配置好以上内容,即可在我们的请求中实现字符串自动去空格。

明白使用其实很简单,我们可以看下在Spring的底层,具体是如何实现Converter的。我们以字符串去空的代码为例。
以上代码,首先实现了Converter接口,我们查看Converter接口的源码。

/**
 * A converter converts a source object of type S to a target of type T.
 * Implementations of this interface are thread-safe and can be shared.
 *
 * 

Implementations may additionally implement {@link ConditionalConverter}. * * @author Keith Donald * @since 3.0 * @see ConditionalConverter * @param The source type * @param The target type */ public interface Converter { /** * Convert the source of type S to target type T. * @param source the source object to convert, which must be an instance of S * @return the converted object, which must be an instance of T * @throws IllegalArgumentException if the source could not be converted to the desired target type */ T convert(S source); }

通过JavaDoc我们可以看到,实现该接口,可以使我们将S类型的对象转换为T类型。那么对应的我们对于Date类型的转换,就可写为如下代码:
public class DateConverter implements Converter

id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

该类的对象,继续查看对应改类的源码,以及对应的JavaDoc。我们可以在该类的Doc中看到如下描述:

* 

Like all {@code FactoryBean} implementations, this class is suitable for * use when configuring a Spring application context using Spring {@code } * XML. When configuring the container with * {@link org.springframework.context.annotation.Configuration @Configuration} * classes, simply instantiate, configure and return the appropriate * {@code FormattingConversionService} object from a * {@link org.springframework.context.annotation.Bean @Bean} method.

该类适用于适用XML构建Spring应用。
我们查看对应的成员变量:

public class FormattingConversionServiceFactoryBean
        implements FactoryBean<FormattingConversionService>, EmbeddedValueResolverAware, InitializingBean {
    private Set> converters;
    private Set> formatters;
    private Set formatterRegistrars;
    private boolean registerDefaultFormatters = true;
    private StringValueResolver embeddedValueResolver;
    private FormattingConversionService conversionService;

在配置XML时,我们主要配置了集合类的converters,该类比较重要的方法如下:

@Override
    public void afterPropertiesSet() {
        this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);
        ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
        registerFormatters();
    }

该方法实现了对conversionService中增减我们对应的格式化器。

在Spring启动时,注册转换器 时会进入afterPropertiesSet 方法。在该方法中,我们可以看到Spring以HashSet来存储对应的converters。在ConversionServiceFactory中,判断不同的转换器,并进行注册。

public static void registerConverters(Set> converters, ConverterRegistry registry) {
        if (converters != null) {
            for (Object converter : converters) {
                if (converter instanceof GenericConverter) {
                    registry.addConverter((GenericConverter) converter);
                }
                else if (converter instanceof Converter, ?>) {
                    registry.addConverter((Converter, ?>) converter);
                }
                else if (converter instanceof ConverterFactory, ?>) {
                    registry.addConverterFactory((ConverterFactory, ?>) converter);
                }
                else {
                    throw new IllegalArgumentException("Each converter object must implement one of the " +
                            "Converter, ConverterFactory, or GenericConverter interfaces");
                }
            }
        }
    }

转载于:https://www.cnblogs.com/jingLongJun/p/4491032.html

你可能感兴趣的:(Converter使用及其原理)