Spring 数据绑定

Spring 数据绑定使用场景

• Spring BeanDefinition 到 Bean 实例创建
• Spring 数据绑定(DataBinder)
• Spring Web 参数绑定(WebDataBinder)

Spring 数据绑定组件

• 标准组件

  • org.springframework.validation.DataBinder

• Web 组件

  • org.springframework.web.bind.WebDataBinder
  • org.springframework.web.bind.ServletRequestDataBinder
  • org.springframework.web.bind.support.WebRequestDataBinder
  • org.springframework.web.bind.support.WebExchangeDataBinder(since 5.0)

• DataBinder 核心属性

属性说明
target关联目标 Bean
objectName目标 Bean名称
bindingResult属性绑定结果
typeConverter类型转换器
conversionService类型转换服务
messageCodesResolver校验错误文案 Code 处理器
validators关联的 Bean Validator 实例集合

• DataBinder 绑定方法

  • bind(PropertyValues):将 PropertyValues Key-Value 内容映射到关联 Bean(target)中的属性上

Spring 数据绑定元数据

• DataBinder 元数据 - PropertyValues

特征说明
数据来源BeanDefinition,主要来源 XML 资源配置 BeanDefinition
数据结构由一个或多个 PropertyValue 组成
成员结构PropertyValue 包含属性名称,以及属性值(包括原始值、类型转换后的值)
常见实现MutablePropertyValues
Web 扩展实现ServletConfigPropertyValues、ServletRequestParameterPropertyValues
相关生命周期InstantiationAwareBeanPostProcessor#postProcessProperties

Spring 数据绑定控制参数

• DataBinder 绑定特殊场景分析

  • 当 PropertyValues 中包含名称 x 的 PropertyValue,目标对象 B 不存在 x 属性,当 bind 方法执行时,会发生什么?
  • 当 PropertyValues 中包含名称 x 的 PropertyValue,目标对象 B 中存在 x 属性,当 bind 方法执行时,如何避免 B 属性 x 不被绑定?
  • 当 PropertyValues 中包含名称 x.y 的 PropertyValue,目标对象 B 中存在 x 属性(嵌套 y 属性),当bind 方法执行时,会发生什么?

• DataBinder 绑定控制参数

参数名称说明
ignoreUnknownFields是否忽略未知字段,默认值:true
ignoreInvalidFields是否忽略非法字段,默认值:false
autoGrowNestedPaths是否自动增加嵌套路径,默认值:true
allowedFields绑定字段白名单
disallowedFields绑定字段黑名单
requiredFields必须绑定字段

BeanWrapper 的使用场景

• Spring 底层 JavaBeans 基础设施的中心化接口
• 通常不会直接使用,间接用于 BeanFactory 和 DataBinder
• 提供标准 JavaBeans 分析和操作,能够单独或批量存储 Java Bean 的属性(properties)
• 支持嵌套属性路径(nested path)
• 实现类 org.springframework.beans.BeanWrapperImpl

Spring 底层 Java Beans 替换实现

• JavaBeans 核心实现 - java.beans.BeanInfo

  • 属性(Property)
    • java.beans.PropertyEditor
  • 方法(Method)
  • 事件(Event)
  • 表达式(Expression)

• Spring 替代实现 - org.springframework.beans.BeanWrapper

  • 属性(Property)
    • java.beans.PropertyEditor
  • 嵌套属性路径(nested path)

DataBinder 数据校验

• DataBinder 与 BeanWrapper

  • bind 方法生成 BeanPropertyBindingResult
  • BeanPropertyBindingResult 关联 BeanWrapper
public class DataBinderDemo {

    public static void main(String[] args) {

        // 创建空白对象
        User user = new User();
        // 1. 创建 DataBinder
        DataBinder binder = new DataBinder(user, "");

        // 2. 创建 PropertyValues
        Map<String, Object> source = new HashMap<>();
        source.put("id", 1);
        source.put("name", "小马哥");

        // a. PropertyValues 存在 User 中不存在属性值
        // DataBinder 特性一 : 忽略未知的属性
        source.put("age", 18);

        // b. PropertyValues 存在一个嵌套属性,比如 company.name
        // DataBinder 特性二:支持嵌套属性
        // Company company = new Company();
        // company.setName("geekbang");
        // user.setCompany(compay)

//        source.put("company", new Company());
        source.put("company.name", "geekbang");

        PropertyValues propertyValues = new MutablePropertyValues(source);

        // 1. 调整 IgnoreUnknownFields true(默认) -> false(抛出异常,age 字段不存在于 User 类)
        // binder.setIgnoreUnknownFields(false);

        // 2. 调整自动增加嵌套路径 true(默认) —> false
        binder.setAutoGrowNestedPaths(false);

        // 3. 调整 ignoreInvalidFields false(默认) -> true(默认情况调整不变化,需要调增 AutoGrowNestedPaths 为 false)
        binder.setIgnoreInvalidFields(true);

        binder.setRequiredFields("id", "name", "city");

        binder.bind(propertyValues);

        // 3. 输出 User 内容
        System.out.println(user);

        // 4. 获取绑定结果(结果包含错误文案 code,不会抛出异常)
        BindingResult result = binder.getBindingResult();
        System.out.println(result);
    }

}

面试题

Spring 数据绑定 API 是什么?
答:org.springframework.validation.DataBinder

BeanWrapper 与 JavaBeans 之间关系是?
答:Spring 底层 JavaBeans 基础设施的中心化接口

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值