Springの力は、Java開発者に大きな利便性を提供するだけでなく、そのオープンアーキテクチャにより、ユーザーがSpringを拡張する最大の能力を持つことができることです。
xmlでBeanを定義する場合、入力コンテンツはすべて文字列です。Springは、登録されたプロパティエディタに従ってこれらの文字列を解析し、対応するタイプにインスタンス化します。
1つ、ソースコード関連
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"));
}
}
実行出力:
Person{
name='bobo', address=Address{
province='广东省', city='深圳市', area='南山区'}}