• 后端——框架——容器框架——spring_core——《官网》阅读笔记——第三章节2(转换器)


      转换器的知识大致可以分为两个部分

    1. 第一部分介绍将配置信息转换为bean对象或bean属性的类型。Spring大部分的配置信息都是字符串
    2. 第二部分介绍任意的类型转换,将A--->B,A,B都可以是任意的类型。

    1、Str2Obj

      Str2Obj的意思是指String to Object。Spring将配置信息转换为bean对象或者bean属性类型至少需要两个步骤

    1. 将字符串转换为属性或对象需要的类型。
    2. 如果是属性,调用对象的setXX方法。

      负责第一步的接口为PropertyEditor,负责调用set方法的接口是BeanWrapper。

    1.1  PropertyEditor

      PropertyEditor接口的职责是将字符串转换为正确的对象类型。

      PropertyEditor接口有很多实现类,spring有许多内置的XXEditor,它们大部分都在org.springframework.beans.propertyeditors。例如最为常见的CustomBooleanEditor,将字符串转换为布尔;CustomDateEditor,将字符串转换为日期。我们也可以自定义XXEditor,实现将字符串转换为自定义类型。

      要使PropertyEditor接口实现类生效,需要实现两个步骤:

    1. 第一步编写PropertyEditor的实现类,或者使用spring框架内置的实现类。
    2. 第二步注册PropertyEditor的实现类。

      第一步较为简单,如果要使用内置的PropertyEditor实现类,参考3.3.2的内容。

      注册PropertyEditor实现类的方式有三种:

    1. 第一种直接将XXPropertyEditor与XX对象放置在同一个包下,例如User类,直接将UserPropertyEditor放置到相同包下即可。
    2. 第二种配置CustomEditorConfigurer的customEditors属性
    <!-- 注入customEditorConfigurer, 并配置customEditors属性   -->
    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    	<!-- 该属性是Map对象,其中key值为转换的对象类型,value值为PropertyEditor接口的实现类 -->
    	<property name="customEditors">
    		<map>
    			<!-- User类为自定义对象,UserPropertyEditor为自定义PropertyEditor接口实现类 -->
    			<entry key="com.bean.User" value="com.propertyEditor.UserPropertyEditor"/>
    		</map>
    	</property>
    </bean>
    

      3.第三种通过实现PropertyEditorRegistrar接口,并将实现类添加到customPropertyEditorRegistrar属性中。

      第一步,编写自定义实现类,实现register方法

    /**
     * 
      * @Title: UserPropertyEditorRegistrar.java  
      * @Package com.propertyEditor  
      * @Description: UserPropertyEditor的注册器
      * @version V1.0
     */
    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);
        }
    }
    

      可以看到第三种注册方式非常繁琐,第一种虽然简单,但是有时候却并不想PropertyEditor放在实体类的包下,spring框架也是将所有的propertyEditor实现类单独放在一个包下,综合比较,第二种方式最优。

    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

      对象与对象之间的转换有很多种实现方式,spring框架只是其中的一种方式。对象转对象大致可以归为三类:

    1. 单个对象转换为单个对象
    2. 单个对象转换为类体系结构,例如String转换为Enum。
    3. 集合相互转换,例如List<String>转换为List<Integer>。

    2.1  Single2Single

      单个对象转换为单个对象有两个步骤:

    1. 第一步实现Convert接口,它只有一个方法convert,参数代表source,方法的返回值为target。
    2. 第二步注册XXConvert。

      注册XXConvert的方式为配置ConversionServiceFactoryBean的converters属性。

    <!-- 注入ConversionServiceFactoryBean -->
    <bean 
    id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    	<!-- 配置converters属性 -->
    	<property name="converters">
    		<set>
    			<!-- 自己编写的convert接口实现类 -->
    			<bean class="com.converts.XXConverter" />
    		</set>
    	</property>
    </bean>
    

      之后就可以获取ConversionServiceFactoryBean的实例,并调用它的API实现转换的功能。

    2.2   Single2ClassHierarchy

      单个对象转换为类体系结构有两个步骤:

    1. 第一步编写ConvertFactory接口的实现类,实现getConverter方法,其中参数代表类结构中具体的类型。返回值为Converter接口实现类,它实现具体的转换逻辑。
    2. 第二步,注册,方法同Converter。

      官网的原示例将String转换为具体的枚举类型,代码如下:

    /**
     * 
      * @Title: StringToEnumConverterFactory.java  
      * @Package com.propertyEditor  
      * @Description: 这个类将String对象转换为具体的枚举类型 
      * @version V1.0
     */
    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.3   Coll2Coll

      多个对象转换为多个对象的步骤和之前类似,区别在于实现GenericConvert接口。待补充。

           注:Spring还提供了ConversionService,它只是整合之前三种接口的功能,应用到了门面模式,步骤和注册方式和之前三种情形基本没什么区别

  • 相关阅读:
    电脑开机时一直滴滴的响开不了机是为什么?
    电脑开机时一直滴滴的响开不了机是为什么?
    winform窗体应用实现淡入淡出等效果
    winform窗体应用实现淡入淡出等效果
    windows-如何生成转储(dmp)文件--工具篇
    面向对象(三)- Java类的方法
    面向对象 (二)- Java类的属性
    面向对象 (二)- Java类的属性
    面向对象 (一)- Java中的类和对象
    面向对象 (一)- Java中的类和对象
  • 原文地址:https://www.cnblogs.com/rain144576/p/12272440.html
Copyright © 2020-2023  润新知