(重拾)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才会自动注册。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值