Spring 数据绑定

Spring 数据绑定

Spring 数据绑定(Data Binding)的作用是将用户的输入动态绑定到 JavaBean。换句话说,Spring 数据绑定机制是将属性值设置到目标对象中。

在 Spring 中,数据绑定功能主要由 DataBinder 类实现。此外,BeanWrapper 也具有类似的功能,但 DataBinder 额外支持字段验证、字段格式化和绑定结果分析。

快速入门

定义一个用于测试的 JavaBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class TestBean {

private int num;

public int getNum() {
return num;
}

public void setNum(int num) {
this.num = num;
}

@Override
public String toString() {
return "TestBean{" + "num=" + num + '}';
}

}

数据绑定示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class DataBindingDemo {

public static void main(String[] args) {

MutablePropertyValues mpv = new MutablePropertyValues();
mpv.add("num", "10");

TestBean testBean = new TestBean();
DataBinder db = new DataBinder(testBean);

db.bind(mpv);
System.out.println(testBean);
}

}

Spring 数据绑定使用场景

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

DataBinder

在 Spring 中,DataBinder 类是数据绑定功能的基类。WebDataBinderDataBinder 的子类,主要用于 Spring Web 数据绑定,此外,还有一些 WebDataBinder 的扩展子类,其类族如下图所示:

DataBinder 核心属性:

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

DataBinder 类的核心方法是 bind(PropertyValues):将 PropertyValues Key-Value 内容映射到关联 Bean(target)中的属性上

  • 假设 PropertyValues 中包含 name=dunwu 的键值对时, 同时 Bean 对象 User 中存在 name 属性, 当 bind 方法执行时, User 对象中的 name 属性值将被绑定为 dunwu

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

问题

标准 JavaBeans 是如何操作属性的?

API 说明
java.beans.Introspector Java Beans 内省 API
java.beans.BeanInfo Java Bean 元信息 API
java.beans.BeanDescriptor Java Bean 信息描述符
java.beans.PropertyDescriptor Java Bean 属性描述符
java.beans.MethodDescriptor Java Bean 方法描述符
java.beans.EventSetDescriptor Java Bean 事件集合描述符

参考资料