深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)

在Spring配置文件或配置类里,我们往往通过字面值为Bean各种类型的属性提供设置值:不管是double类型还是int类型,在配置文件中都对应字符串类型的字面值。BeanWrapper填充Bean属性时如何将这个字面值转换为对应的double或int等内部类型呢?我们可以隐约地感觉到一定有一个转换器在其中起作用,这个转换器就是属性编辑器。

一、 PropertyEditor

PropertyEditor是属性编辑器的接口,它规定了将外部设置值转换为内部JavaBean属性值的转换接口方法。PropertyEditor主要的接口方法说明如下: 
· Object getValue():返回属性的当前值。基本类型被封装成对应的封装类实例; 
· void setValue(Object newValue):设置属性的值,基本类型以封装类传入; 
· String getAsText():将属性对象用一个字符串表示,以便外部的属性编辑器能以可视化的方式显示。缺省返回null,表示该属性不能以字符串表示; 
· void setAsText(String text):用一个字符串去更新属性的内部值,这个字符串一般从外部属性编辑器传入; 
· String[] getTags():返回表示有效属性值的字符串数组(如boolean属性对应的有效Tag为true和false),以便属性编辑器能以下拉框的方式显示出来。缺省返回null,表示属性没有匹配的字符值有限集合; 
· String getJavaInitializationString():为属性提供一个表示初始值的字符串,属性编辑器以此值作为属性的默认值。

可以看出PropertyEditor接口方法是内部属性值和外部设置值的沟通桥梁。此外,我们可以很容易地发现该接口的很多方法是专为IDE中的可视化属性编辑器提供的:如getTags()、getJavaInitializationString()以及另外一些我们未此介绍的接口方法。

PropertyEditorSupport

Java为PropertyEditor提供了一个方便类:PropertyEditorSupport,该类实现了PropertyEditor接口并提供默认实现,一般情况下,用户可以通过扩展这个方便类设计自己的属性编辑器。

二、 Spring内置属性编辑器

        Spring框架内置了一些PropertyEditor来对,并且bean填充属性之前都会把这些PropertyEditor添加到BeanWrapper中(在Spring IOC容器bean初始化源码分析有分析),代码在PropertyEditorRegistrySupport类的createDefaultEditors方法中:

实例化Bean并使用BeanWrapper包装Bean实例后,调用initBeanWrapper(),在此方法中检查AbstractBeanFactory的变量propertyEditorRegistrars是否注册了PropertyEditorRegistrar(ResourceEditorRegistrar在Spring加载并刷新容器时,注册至propertyEditorRegistrars属性),执行注册的PropertyEditorRegistrar.registerCustomEditors(),同时将自定义的属性编辑器注册至PropertyEditorRegistrySupport.customEditors(BeanWrapperImpl继承了PropertyEditorRegistrySupport)属性中

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第1张图片

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第2张图片

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第3张图片


此外还内置了一些Resource相关的PropertyEditor,代码在ResourceEditorRegistrar类的registerCustomEditors方法中:

AbstractApplicationContext.refresh()-->prepareBeanFactory()中注册了ResourceEditorRegistrar

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第4张图片

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第5张图片

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第6张图片


PropertyEditorRegistry属性编辑器注册

这个接口可以注册和保存属性编辑器

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第7张图片

PropertyEditorRegistrySupport

PropertyEditorRegistrySupport是PropertyEditorRegistry 默认实现类 ,PropertyEditorRegistrySupport中有两个用于保存属性编辑器的Map类型变量defalutEditors和customEditors

BeanWrapperImpl实现了PropertyEditorRegistrySupport

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第8张图片

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第9张图片

Spring使用了懒注册的方式,在通过属性类型获取编辑器时,当默认的属性编辑器注册变量defaultEditors为Null时,再调用

createDefaultEditors()注册默认的属性编辑器

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第10张图片

Spring注册的默认属性编辑器清单详见createDefaultEditors()函数中代码处理

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第11张图片

三、 自定义属性编辑器的注册及查找使用

CustomEditorConfigurer.postProcessBeanFactory()-->ConfigurableListableBeanFactory.registerCustomEditor()

1、spring中的属性编辑器

Spring大部分默认属性编辑器都直接扩展于java.beans.PropertyEditorSupport类,用户也可以通过扩展PropertyEditorSupport实现自己的属性编辑器。比起用于IDE环境的属性编辑器来说,Spring环境下使用的属性编辑器的功能非常单一:仅需要将配置文件中字面值转换为属性类型的对象即可,并不需要提供UI界面,因此仅需要简单覆盖PropertyEditorSupport的setAsText()方法就可以了

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第12张图片

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第13张图片

2、注册自定义属性编辑器

   使用ApplicationContext,只需要在配置文件中通过CustomEditorConfigurer注册即可。CustomEditorConfigurer实现了BeanFactoryPostProcessor接口,因而是一个Bean工厂后置处理器,在Spring容器中加载配置文件并生成BeanDefinition后会被执行。CustomEditorConfigurer在容器启动时有机会注册自定义的属性编辑器

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第14张图片

AbstractBeanFactory Bean工厂中提供了customEditors自定义编辑器注册清单存储

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第15张图片

调用了CustomEditorConfigurer中的postProcessBeanFactory()方法,会将配置的自定义编辑器注册至

AbstractBeanFactory中的customEditors存储器中

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第16张图片



深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第17张图片

编辑器注册后,在使用时通过findCustomEditor()指定属性类型,查找默认和自定义属性编辑器将字面量的值转换为属性定义的

类型对象

深入分析Spring属性编辑器(默认属性编辑器和自定义属性编辑器)_第18张图片

你可能感兴趣的:(Spring,PropertyEditor,自定义属性编辑器)