spring 22 对象绑定与类型转换
作者:互联网
底层第一套转换接口与实现
classDiagram Formatter --|> Printer Formatter --|> Parser class Converters { Set~GenericConverter~ } class Converter class ConversionService class FormattingConversionService ConversionService <|-- FormattingConversionService FormattingConversionService o-- Converters Printer --> Adapter1 Adapter1 --> Converters Parser --> Adapter2 Adapter2 --> Converters Converter --> Adapter3 Adapter3 --> Converters <<interface>> Formatter <<interface>> Printer <<interface>> Parser <<interface>> Converter <<interface>> ConversionService- Printer 把其它类型转为 String
- Parser 把 String 转为其它类型
- Formatter 综合 Printer 与 Parser 功能
- Converter 把类型 S 转为类型 T
- Printer、Parser、Converter 经过适配转换成 GenericConverter 放入 Converters 集合
- FormattingConversionService 利用其它们实现转换
底层第二套转换接口
classDiagram PropertyEditorRegistry o-- "多" PropertyEditor <<interface>> PropertyEditorRegistry <<interface>> PropertyEditor- PropertyEditor 把 String 与其它类型相互转换
- PropertyEditorRegistry 可以注册多个 PropertyEditor 对象
- 与第一套接口直接可以通过 FormatterPropertyEditorAdapter 来进行适配
高层接口与实现
classDiagram TypeConverter <|-- SimpleTypeConverter TypeConverter <|-- BeanWrapperImpl TypeConverter <|-- DirectFieldAccessor TypeConverter <|-- ServletRequestDataBinder SimpleTypeConverter --> TypeConverterDelegate BeanWrapperImpl --> TypeConverterDelegate DirectFieldAccessor --> TypeConverterDelegate ServletRequestDataBinder --> TypeConverterDelegate TypeConverterDelegate --> ConversionService TypeConverterDelegate --> PropertyEditorRegistry <<interface>> TypeConverter <<interface>> ConversionService <<interface>> PropertyEditorRegistry- 它们都实现了 TypeConverter 这个高层转换接口,在转换时,会用到 TypeConverter Delegate 委派ConversionService 与 PropertyEditorRegistry 真正执行转换(Facade 门面模式)
- 首先看是否有自定义转换器, @InitBinder 添加的即属于这种 (用了适配器模式把 Formatter 转为需要的 PropertyEditor)
- 再看有没有 ConversionService 转换
- 再利用默认的 PropertyEditor 转换
- 最后有一些特殊处理
- SimpleTypeConverter 仅做类型转换
- BeanWrapperImpl 为 bean 的属性赋值,当需要时做类型转换,走 Property
- DirectFieldAccessor 为 bean 的属性赋值,当需要时做类型转换,走 Field
- DataBinder 普通环境下的属性数据绑定类型转换
- ServletRequestDataBinder 为 bean 的属性执行绑定,当需要时做类型转换,根据 directFieldAccess 选择走 Property 还是 Field,具备校验与获取校验结果功能
类型转换与数据绑定
点击查看代码
//仅有类型转换功能
SimpleTypeConverter converter = new SimpleTypeConverter();
System.out.println(converter.convertIfNecessary("11", int.class));
System.out.println(converter.convertIfNecessary("2011/01/02", Date.class));
//类型转换与数据绑定 ,根据反射,用 set 方法为 bean 属性赋值
BeanWrapperImpl beanWrapper = new BeanWrapperImpl();
S22Bean1 s22Bean1 = new S22Bean1();
beanWrapper.setBeanInstance(s22Bean1);
beanWrapper.setPropertyValue("name",13);
beanWrapper.setPropertyValue("age","32");
beanWrapper.setPropertyValue("date","2011/11/20");
System.out.println(s22Bean1);
//类型转换与数据绑定, 利用反射,直接赋值给 bean 的属性,不需要 set 方法
S22Bean2 s22Bean2 = new S22Bean2();
DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(s22Bean2);
fieldAccessor.setPropertyValue("name",22);
fieldAccessor.setPropertyValue("age","19");
System.out.println(s22Bean2);
//类型转换与数据绑定,根据 DirectFieldAccess 存不存在判断用哪种方法数据绑定 默认用 set 方法
S22Bean2 s22Bean2 = new S22Bean2();
DataBinder dataBinder = new DataBinder(s22Bean2);
dataBinder.initDirectFieldAccess();
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add("name", 34);
propertyValues.add("age", "12");
dataBinder.bind(propertyValues);
System.out.println(s22Bean2);
//类型转换与数据绑定,根据 DirectFieldAccess 存不存在判断用哪种方法数据绑定 默认用 set 方法
S22Bean2 s22Bean2 = new S22Bean2();
DataBinder dataBinder = new ServletRequestDataBinder(s22Bean2);
//可直接对属性进行绑定
dataBinder.initDirectFieldAccess();
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("name","13");
request.setParameter("age","13");
request.setParameter("date","2011/2/2");
ServletRequestParameterPropertyValues propertyValues = new ServletRequestParameterPropertyValues(request);
//也可以使用此方式进行数据绑定类型转换
// propertyValues.add("name", 34);
// propertyValues.add("age", "12");
dataBinder.bind(propertyValues);
System.out.println(s22Bean2);
- SimpleTypeConverter
- BeanWrapperImpl
- DirectFieldAccessor
- ServletRequestDataBinder
数据绑定工厂
点击查看代码
- 可以解析控制器的 @InitBinder 标注方法作为扩展点,添加自定义转换器
- 控制器私有范围
- 可以通过 ConfigurableWebBindingInitializer 配置 ConversionService 作为扩展点,添加自定义转换器
- 公共范围
- 同时加了 @InitBinder 和 ConversionService 的转换优先级
- 优先采用 @InitBinder 的转换器
- 其次使用 ConversionService 的转换器
- 使用默认转换器
- 特殊处理(例如有参构造)
获取泛型参数
点击查看代码
标签:类型转换,22,--,spring,绑定,s22Bean2,ConversionService,new 来源: https://www.cnblogs.com/xy7112/p/16437801.html