转换器的知识点有两部分,
第一部分是将配置信息转换为对象,本质是将配置信息的字符串转换为属性的类型。适用于属性层次
第二部分是实现对象的互相转换,两种,单个对象的相互转换。集合之间的相互转换。
1、str2Obj
配置信息转换为对象,两个步骤。
提供所需要的转换器,并注册。转换器为PropertyEditor接口的实现类。
设置属性值,通常由BeanWrapper实现。
1.1 PropertyEditor
编写PropertyEditor的接口实现类,比较简单,略,可以参考CustomBooleanEditor。
注册PropertyEditor接口的方式有三种。
第一种方式,将XXEditor与目标对象存放在同一包下。使用频率低,但是最简便。
第二种方式,配置CustomEditorConfigurer的customEditors属性。
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.bean.User" value="com.propertyEditor.UserPropertyEditor"/>
</map>
</property>
</bean>
第三种方式,实现PropertyEditorRegistrar接口,并将实现类添加到customPropertyEditorRegistrar属性中。
示例如下:
接口实现类UserPropertyEditorRegistar
public class UserPropertyEditorRegistrar implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry registry) {
// 第一个参数为对象的类型,这里是User.class,// 第二个参数为UserPropertyEditor的实例
registry.registerCustomEditor(User.class, new UserPropertyEditor());
}
}
配置CustomEditorConfigurer的propertyEditorRegistrars属性
<!-- 注入XXPropertyRegistrars --> <bean id="userEditorRegistrar" class="com.propertyEditor.UserPropertyEditorRegistrar"/> <!-- 注入customEditorConfigurer, 并配置customEditors属性 --> <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <!-- 配置propertyEditorRegistrars属性 --> <property name="propertyEditorRegistrars"> <list> <ref bean="userEditorRegistrar"> </list> </property> </bean>
第三步,在Controller类中获取XXPropertyRegistrars,在initBinder方法中调用registerCustomEditors。
public final class RegisterUserController {
@Autowired
private final PropertyEditorRegistrar customPropertyEditorRegistrar;
public RegisterUserController(PropertyEditorRegistrar propertyEditorRegistrar) {
this.customPropertyEditorRegistrar = propertyEditorRegistrar;
}
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
// 这一步是关键
this.customPropertyEditorRegistrar.registerCustomEditors(binder);
}
}
1.2 BeanWrapper
通过BeanWrapper设置对象的某个属性,下例中有两种设置User的name属性的方式。
BeanWrapper user = new BeanWrapperImpl(new User());
// 设置user的名称
user.setPropertyValue("name", "张三");
// 第二种方式,通过创建PropertyValue对象设置user的名称
PropertyValue value = new PropertyValue("name", "张三");
user.setPropertyValue(value);
2、obj2obj
归为两类,对象之间的互相转换,集合之间的互相转换。
2.1 single2single
两种实现方式,第一种通过ConversionServiceFactoryBean,第二种通过ConvertFactory。
ConversionServiceFactoryBean实现步骤两步,
第一步,实现Convert接口,参数代表source,方法的返回值为dest。
第二步,注册。配置ConversionServiceFactoryBean的converters属性。
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <!-- 配置converters属性 --> <property name="converters"> <set> <!-- 自己编写的convert接口实现类 --> <bean class="com.converts.XXConverter" /> </set> </property> </bean>
ConvertFactory实现步骤也是两步,
第一步,实现ConvertFactory,它有两个泛型参数,第一个为source,第二个为dest。
第二步,注册。同ConversionServiceFactoryBean。
public final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
// 这个是ConvertFactory接口中的方法,它只是获取具体的Converter
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
return new StringToEnumConverter(targetType);
}
// Converter接口的实现类,不必是内部类的形式
private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> {
private Class<T> enumType;
public StringToEnumConverter(Class<T> enumType) {
this.enumType = enumType;
}
public T convert(String source) {
return (T) Enum.valueOf(this.enumType, source.trim());
}
}
}
2.2 collection2collection
多个对象转换为多个对象的步骤和之前类似,区别在于实现GenericConvert接口。
注:Spring还提供了ConversionService。