吃透Spring源码:自定义属性编辑器PropertyEditor
Posted 吃透Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了吃透Spring源码:自定义属性编辑器PropertyEditor相关的知识,希望对你有一定的参考价值。
Spring的强大之处不仅仅在于它为Java开发者提供了极大便利,更在于它的开放式架构,使得用户可以拥有最大扩展Spring的能力。
我们在xml定义bean时,输入的内容都是字符串。spring会根据已经注册好的属性编辑器解析这些字符串,实例化成对应的类型。
一,源码相关
1,创建默认的propertyEditorRegister
在AbstractApplicationContext的refresh()方法的prepareBeanFactory()方法中创建一个默认的PropertyEditorRegister放入beanFactory中,此类主要负责注入如下默认的属性编辑器:
public void registerCustomEditors(PropertyEditorRegistry registry)
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, ContextResource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
if (this.resourceLoader instanceof ResourcePatternResolver)
doRegisterEditor(registry, Resource[].class,
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor)
if (registry instanceof PropertyEditorRegistrySupport)
((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
else
registry.registerCustomEditor(requiredType, editor);
2,调用registerCustomEditors来完成PropertyEditor的注册
spring源码在实例化bean的时候,创建完BeanWrapperImpl之后会调用registerCustomEditors()方法来遍历所有的propertyEditorRegister(包括我们自定义的propertyEditorRegister)类来完成属性编辑器的注入。如下:
protected void initBeanWrapper(BeanWrapper bw)
bw.setConversionService(getConversionService());
registerCustomEditors(bw);
3,调用PropertyEditor来完成属性的解析
在populateBean对属性填充时会遍历每一个属性值来获取对应的属性编辑器,然后调用对应的属性编辑器(PropertyEditor)的setAsText()方法来解析对应的值。
二,案例
Address.java
package com.bobo.customeditor;
/**
* @author bobo
* @date 2020-10-21
*/
public class Address
private String province;
private String city;
private String area;
public String getProvince()
return province;
public void setProvince(String province)
this.province = province;
public String getCity()
return city;
public void setCity(String city)
this.city = city;
public String getArea()
return area;
public void setArea(String area)
this.area = area;
@Override
public String toString()
return "Address" +
"province='" + province + '\\'' +
", city='" + city + '\\'' +
", area='" + area + '\\'' +
'';
Person.java
package com.bobo.customeditor;
/**
* @author bobo
* @date 2020-10-21
*/
public class Person
private String name;
private Address address;
public String getName()
return name;
public void setName(String name)
this.name = name;
public Address getAddress()
return address;
public void setAddress(Address address)
this.address = address;
@Override
public String toString()
return "Person" +
"name='" + name + '\\'' +
", address=" + address +
'';
AddressPropertyEditor
package com.bobo.customeditor;
import java.beans.PropertyEditorSupport;
/**
* @author bobo
* @date 2020-10-21
*/
public class AddressPropertyEdit extends PropertyEditorSupport
@Override
public void setAsText(String text) throws IllegalArgumentException
String[] split = text.split("-");
Address address = new Address();
address.setProvince(split[0]);
address.setCity(split[1]);
address.setArea(split[2]);
setValue(address);
AddressPropertyEditorRegister.java
package com.bobo.customeditor;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
/**
* @author bobo
* @date 2020-10-21
*/
public class AddressPropertyEditorRegister implements PropertyEditorRegistrar
@Override
public void registerCustomEditors(PropertyEditorRegistry registry)
registry.registerCustomEditor(Address.class,new AddressPropertyEdit());
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.bobo.customeditor.Person">
<property name="name" value="bobo"/>
<property name="address" value="广东省-深圳市-南山区"/>
</bean>
<!--第一种方式-->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<list>
<bean class="com.bobo.customeditor.AddressPropertyEditorRegister"></bean>
</list>
</property>
</bean>
<!--第二种方式-->
<!-- <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">-->
<!-- <property name="customEditors">-->
<!-- <map>-->
<!-- <entry key="com.bobo.customeditor.Address">-->
<!-- <value>com.bobo.customeditor.AddressPropertyEdit</value>-->
<!-- </entry>-->
<!-- </map>-->
<!-- </property>-->
<!-- </bean>-->
</beans>
test.java
package com.bobo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test
public static void main(String[] args)
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
System.out.println(context.getBean("person"));
运行输出:
Personname='bobo', address=Addressprovince='广东省', city='深圳市', area='南山区'
以上是关于吃透Spring源码:自定义属性编辑器PropertyEditor的主要内容,如果未能解决你的问题,请参考以下文章