我们在xml定义bean时,输入的内容都是字符串。spring会根据已经注册好的属性编辑器解析这些字符串,实例化成对应的类型。下面看一个具体案例,Customer有一个属性Address,根据自定的属性编辑器生成Address对象,并解析出“省市区”。
步骤如下:
1 自定义一个实现了PropertyEditorSupport接口的编辑器
2 让Spring能够识别到此编辑器,自定义实现一个属性编辑器的注册器,实现了PropertyEditorRegistrar接口
3 让spring能够识别到对应的注册器,这里CustomEditorConfigurer来识别
下面开始:定义一个address 对象
定义一个Customer对象,包含Address对象
定义一个AddressPropertyEditor继承PropertyEditorSupport类
定义AddressPropertyEditorRegistrar实现接口:PropertyEditorRegistrar
定义xml
测试:
结果:
下面我们来具体看源码分析,为什么是这样做的呢?
先进入到refresh方法
看到这里没有,添加的ResourceEditorRegistrar,这是Spring自带的属性编辑器
同时可以看到父接口,有一个方法registerCustomEditors
再回到子类:ResourceEditorRegistrar
那么时候调用这个方法registerCustomEditors呢?
我们从之前分析bean的生命周期的时候,如下图:
在填充属性的时候执行的,那继续看源代码:
看下面的具体类是:CustomEditorConfigurer
也就是说:属性编辑器就由CustomEditorConfigurer类来管理的
先来看下这个CustomEditorConfigurer,实现了BeanFactoryPostProcessor接口
我们知道BeanFactoryPostProcessor接口有一个方法postProcessBeanFactory
同样CustomEditorConfigurer也要实现这个接口:
那么是什么时候执行的呢,继续debug
执行到我们自定义的AddressPropertyEditorRegistrar
到这里还只是添加了我们自定义的AddressPropertyEditorRegistrar类,并没有执行具体的解析工作,下面继续从设置属性来看具体的执行过程
初始化对象后,属性都是默认空值
接下来,属性填充
接下来到了属性解析
终于找到了我们自己的属性编辑器了
下面进行解析
解析asText方法了
到了我们自己定义的setAsText方法中了
解析结果:
当然spring默认提供以下属性编辑器,不用注册
ClassEditor 使用包含全称名的字符串设置java.lang.Class属性
CustomDateEditor 使用某种java.text.DateFormat对象将一个字符串设置给java.util.Date属性
FileEditor 使用包含文件路径的字符串设置java.io.File属性
LocalEditor 设置java.util.Local属性
StringArrayPropertyEditor 将一个包含逗号的String转化成String数组
StringTrimmerEditor 自动修正字符串属性,可以选择将空字符转变成null
自定义属性编辑器就聊到这里吧。