Spring源码探究之属性编辑器(PropertyEditorSupport)
概述
Spring容器在启动时会通过加载配置文件或者配置类的方式将定义的每个javaBean解析成BeanDefinition类型的对象,而javabean对象的属性被解析储存在BeanDefinition对象MutablePropertyValues属性中。
为什么会有属性编辑器这个东西?、
从代码角度分析
我们知道java对象中的变量属性都是有类型的(java基础类型或者对象类型等等),既然是有类型的,那在定义属性的时候就必须有类型的定义,可是Spring不提供这样的定义或者不采用你所定义的类型,所以需要属性编辑器这个东西来控制属性的类型
下面从两种配置方式来详解解释
1、xml方式配置(如下图)
这是一个标准的也是常见的配置xml配置方式,不提工类型的定义
从上图可以看出,可以定义属性的name和value,但是没有定义属性类型的参数
此时可能有同学会提问了,java配置呢?
2、java方式配置(如下图)
不采用定义的类型
这是一个简单对象的配置,有人会说,我这边不是传进去一个Date类型的值吗,类型不就知道了,其实这只是表象
请继续看下面Spring解析属性的过程
Spring解析属性的过程
public class BeanDefinitionParserDelegate {
...此处省略n行代码...
public void parsePropertyElement(Element ele, BeanDefinition bd) {
String propertyName = ele.getAttribute("name");
if (!StringUtils.hasLength(propertyName)) {
this.error("Tag 'property' must have a 'name' attribute", ele);
} else {
this.parseState.push(new PropertyEntry(propertyName));
try {
if (!bd.getPropertyValues().contains(propertyName)) {
Object val = this.parsePropertyValue(ele, bd, propertyName);
PropertyValue pv = new PropertyValue(propertyName, val);
this.parseMetaElements(ele, pv);
pv.setSource(this.extractSource(ele));
bd.getPropertyValues().addPropertyValue(pv);
return;
}
this.error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
} finally {
this.parseState.pop();
}
}
}
...此处省略n行代码...
}
从上面代码可以看出,属性值经过parsePropertyValue方法解析后得到的是一个Object对象,也就是说,无论你写成你认为的什么值进来,最终都被定义成Object类型的值封装成PropertyValue类型的对象存储在BeanDefinition对象的MutablePropertyValues属性中
图解(PS:请原谅作者这三流的画图技术)
如何实现属性编辑器
1.自定义属性编辑器
Spring提供了PropertyEditorSupport基类,只要自定义类继承它,并且重写内部的setAsText方法,即可实现
如下图:以日期属性为例
2.注册自定义属性编辑器
将自定义的属性编辑器作为CustomEditorConfigurer类的属性值注册
demo代码地址:https://github.com/nadion/Spring-PropertyEditorSupport
欢迎各路大神指正~!!!