天天看点

conversionService类型转换类源码详解

conversionService是spring中的从前端到后端的类型转换器,一般我们会配置<mvc:annotation-driven/>或者自己手动配置HandlerMapping和HandlerAdapter。如果需要从前端页面的字符串自动映射成Date类型等类型转换,我们就要自己手动配置conversionService。

<bean
            class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="webBindingInitializer">
            <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
                <!--时间、数字格式转换器,string转Date类等-->
                <property name="conversionService">
                    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"></bean>
                </property>
            </bean>
        </property>
    </bean>
           

conversionService是AnnotationMethodHandlerAdapter类中的webBindingInitializer的一个属性,我们看下此类的类型关系:

conversionService类型转换类源码详解

我们看到了InitializingBean这个类,那么我们要进入其afterPropertiesSet()方法中查看一下了,

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

我们重点看下标红的这块代码,后面我们会进入到addDefaultFormatters方法中:

public DefaultFormattingConversionService(StringValueResolver embeddedValueResolver, boolean registerDefaultFormatters) {
		this.setEmbeddedValueResolver(embeddedValueResolver);
		DefaultConversionService.addDefaultConverters(this);
		if (registerDefaultFormatters) {
			addDefaultFormatters(this);
		}
	}
           
public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {
   formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
   if (jodaTimePresent) {
      new JodaTimeFormatterRegistrar().registerFormatters(formatterRegistry);
   } else {
      formatterRegistry.addFormatterForFieldAnnotation(new NoJodaDateTimeFormatAnnotationFormatterFactory());
   }
}      

我们看到上面有一个判断是jodaTimePresent,这个是什么呢:

private static final boolean jodaTimePresent = ClassUtils.isPresent(
			"org.joda.time.LocalDate", DefaultFormattingConversionService.class.getClassLoader());
           

这个是判断项目中是否能加载出org.joda.time.LocalDate这个类,这个类在什么地方呢,我们就需要引入jar包,否则,就算你前面spring中做了配置,也无法让spring加载时间转换器,此时引入此jar包即可:

<dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.3</version>
        </dependency>
           

继续阅读