转换器的知识点有两部分,
第一部分是将配置信息转换为对象,本质是将配置信息的字符串转换为属性的类型。适用于属性层次
第二部分是实现对象的互相转换,两种,单个对象的相互转换。集合之间的相互转换。
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。