`

(重拾)Spring之类型转换器

 
阅读更多
因为非常的简单,原则就不说明了,与属性转换器差不多功能,针对的是全局的类型.
Spring配置如下:
<bean id="customConvertConfigurer"
		class="org.springframework.context.ConvertsBeanFactoryPostProcessor">
		
		<property name="converters">
			 <list>
			 	<ref bean="dataConverter" />
			 </list>
		</property> 
	</bean>
	
	<bean id="dataConverter" class="org.springframework.context.DateConverter" >
			<property name="formats">  
				<list>
					<value>yyyy-MM-dd</value>
					<value>yyyy-MM-dd HH:mm:ss</value>
				</list>
			</property> 
	</bean>


不解释,源码如下:
package org.springframework.context;

import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;

public class ConvertsBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	
	public List<Converter<?, ?>> converters;
 
 
	public void setConverters(List<Converter<?, ?>> converters) {
		this.converters = converters;
	} 
	
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		DefaultConversionService dcs = new DefaultConversionService();
		for(Converter<?, ?> converter:converters){
			dcs.addConverter(converter);
		}
		beanFactory.setConversionService(dcs);
	}

}

大家不要搞错了,spring源码中是没有这个类的,自己写的.
package org.springframework.context;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.springframework.core.convert.converter.Converter;

public class DateConverter implements Converter<String, Date>{
	
	private List<String> formats; 
	
	public void setFormats(List<String> formats) {
		this.formats = formats;
	} 

	public Date convert(String text) { 
		Date date = null;
		try {
			SimpleDateFormat sdf = null; 
			if(text.length() == 10){
				sdf = new SimpleDateFormat((String)formats.get(0));
			}else if(text.length() == 19){
				sdf = new SimpleDateFormat((String)formats.get(1));
			} 
			date= sdf.parse(text); // 获取时间信息 
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

}


接口很简单,支持泛型,支持任何类型的转换,在转换之前spring会自动根据String,Date生成一个类型转换器的key,然后是根据这个key来获取类型转换器的。

所以他比属性转换器优秀,属性转换器是根据目标类型作匹配的.

类型转换器接口简单,而且使用的是泛型,扩展性强.

测试代码如下:
		TestBean tt = (TestBean)xct.beanFactory.getBean("jenny");
		System.out.println(tt.getAge());
		System.out.println(tt.getName());
		System.out.println(tt.getDateValue()); 


类型转换器除了在Spring的注册机制与属性转换器相似外(更优),而且很容易抽离Spring框架使用。

稍微修改一下代码
package org.springframework.context;

import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;

public class ConvertsBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	
	public List<Converter<?, ?>> converters;
	
	public ConversionService conversionService;
 
 
	public void setConverters(List<Converter<?, ?>> converters) {
		this.converters = converters;
	} 
	
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		DefaultConversionService dcs = new DefaultConversionService();
		for(Converter<?, ?> converter:converters){
			dcs.addConverter(converter);
		}
		beanFactory.setConversionService(dcs);
		conversionService = beanFactory.getConversionService();
	}
	
	/**
	 * 是否支持源类型到目标类型的转换
	 * 
	 * @param source
	 * @param target
	 * @return
	 */
	public boolean canConverter(Class<?> sourceType,Class<?> targetType){ 
		return conversionService.canConvert(sourceType, targetType); 
	}
	
	/**
	 * 执行类型转换
	 * 
	 * @param source
	 * @param target
	 * @return
	 */
	public Object convert(Object source,Class<?> targetType){
		return conversionService.convert(source, targetType);
	}

}


测试代码如下
ConvertsBeanFactoryPostProcessor cbf = (ConvertsBeanFactoryPostProcessor)xct.beanFactory.getBean("customConvertConfigurer");
		cbf.canConverter(String.class, Date.class);
		System.out.println(cbf.convert("2011-01-11", Date.class));


这种设计原理很简单,类型转换器注册和使用,至于是Spring内部使用,还是外部使用都可以。根据这种设计原理,当今数据库mysql,oracle,hbase.mongodb等的类型与Java中的自定义类型都不一致,完全可以做一个Convert,做个类型兼容.

当然spring也有提供注册方法,它写的很丑,强加的
    <bean id="conversionService" class=
            "org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <ref bean="dataConverter" />
            </list>
        </property>
    </bean> 

有多丑啊,可以说要多丑有多丑,这种代码的加载会污染整个Spring的设计.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

代码强依赖,你的beanName必须为conversionService才会自动注册。
分享到:
评论

相关推荐

    java面试宝典

    53、数据类型之间的转换: 14 54、字符串操作:如何实现字符串的反转及替换? 14 55、编码转换:怎样将GB2312 编码的字符串转换为ISO-8859-1 编码的字符串? 14 56、写一个函数,要求输入一个字符串和一个字符长度,...

    最新Java面试宝典pdf版

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 81 三. html&JavaScript&ajax部分 82 1. 判断第二个日期比第一个日期大 82 2. 用table显示n条记录,每3行换一次...

    Java面试宝典-经典

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 81 三. html&JavaScript&ajax部分 82 1. 判断第二个日期比第一个日期大 82 2. 用table显示n条记录,每3行换一次...

    JAVA面试宝典2010

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 81 三. html&JavaScript&ajax部分 82 1. 判断第二个日期比第一个日期大 82 2. 用table显示n条记录,每3行换一次...

    java面试题大全(2012版)

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 81 三. html&JavaScript;&ajax;部分 82 1. 判断第二个日期比第一个日期大 82 2. 用table显示n条记录,每3行换一次...

    java面试宝典2012

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 88 三. html&JavaScript;&ajax;部分 89 1. 判断第二个日期比第一个日期大 89 2. 用table显示n条记录,每3行换一次...

    Java面试宝典2012版

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 81 三. html&JavaScript;&ajax;部分 82 1. 判断第二个日期比第一个日期大 82 2. 用table显示n条记录,每3行换...

    Java面试宝典2012新版

    12.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-&gt;(一千零一拾一元整)输出。 81 三. html&JavaScript;&ajax;部分 82 1. 判断第二个日期比第一个日期大 82 2. 用table显示n条记录,每3行换一次...

Global site tag (gtag.js) - Google Analytics