關於Spring屬性編輯器詳解

最近剛在研究Spring的編輯器,發現很有意思,剛好galaxystar起了一個這樣貼,我想對PropertyEditor作一個詳細的整理會對大家有益,特定啓了這個新帖。

所謂的PropertyEditor,顧名思義,就是屬性編輯器。由於Bean屬性通過配置文檔以字符串了方式爲屬性賦值,所以必須有一個“東東”負責將這個字符串轉換爲屬性的直接對象,如屬性的類型爲int,那麼編輯器要做的工作就是int i = Integer.parseInt("1");
Spring爲一般的屬性類型提供了默認的編輯器,BeanWrapperImpl是Spring框架中重要的類,它負責對注入的Bean進行包裝化的管理,常見屬性類型對應的編輯器即在該類中通過以下代碼定義:


代碼
private void registerDefaultEditors()
{
// Simple editors, without parameterization capabilities.
// The JDK does not contain a default editor for any of these target types.
this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
this.defaultEditors.put(Class.class, new ClassEditor());
this.defaultEditors.put(File.class, new FileEditor());
this.defaultEditors.put(InputStream.class, new InputStreamEditor());
this.defaultEditors.put(Locale.class, new LocaleEditor());
this.defaultEditors.put(Properties.class, new PropertiesEditor());
this.defaultEditors.put(Resource[].class,
new ResourceArrayPropertyEditor());
this.defaultEditors.put(String[].class, new StringArrayPropertyEditor());
this.defaultEditors.put(URL.class, new URLEditor());

// Default instances of collection editors.
// Can be overridden by registering custom instances of those as custom editors.
this.defaultEditors.put(Collection.class,
new CustomCollectionEditor(Collection.class));
this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
this.defaultEditors.put(SortedSet.class,
new CustomCollectionEditor(SortedSet.class));
this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));

// Default instances of character and boolean editors.
// Can be overridden by registering custom instances of those as custom editors.
PropertyEditor characterEditor = new CharacterEditor(false);
PropertyEditor booleanEditor = new CustomBooleanEditor(false);

// The JDK does not contain a default editor for char!
this.defaultEditors.put(char.class, characterEditor);
this.defaultEditors.put(Character.class, characterEditor);

// Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
this.defaultEditors.put(boolean.class, booleanEditor);
this.defaultEditors.put(Boolean.class, booleanEditor);

// The JDK does not contain default editors for number wrapper types!
// Override JDK primitive number editors with our own CustomNumberEditor.
PropertyEditor byteEditor = new CustomNumberEditor(Byte.class, false);
PropertyEditor shortEditor = new CustomNumberEditor(Short.class, false);
PropertyEditor integerEditor = new CustomNumberEditor(Integer.class, false);
PropertyEditor longEditor = new CustomNumberEditor(Long.class, false);
PropertyEditor floatEditor = new CustomNumberEditor(Float.class, false);
PropertyEditor doubleEditor = new CustomNumberEditor(Double.class, false);

this.defaultEditors.put(byte.class, byteEditor);
this.defaultEditors.put(Byte.class, byteEditor);

this.defaultEditors.put(short.class, shortEditor);
this.defaultEditors.put(Short.class, shortEditor);

this.defaultEditors.put(int.class, integerEditor);
this.defaultEditors.put(Integer.class, integerEditor);

this.defaultEditors.put(long.class, longEditor);
this.defaultEditors.put(Long.class, longEditor);

this.defaultEditors.put(float.class, floatEditor);
this.defaultEditors.put(Float.class, floatEditor);

this.defaultEditors.put(double.class, doubleEditor);
this.defaultEditors.put(Double.class, doubleEditor);

this.defaultEditors.put(BigDecimal.class,
new CustomNumberEditor(BigDecimal.class, false));
this.defaultEditors.put(BigInteger.class,
new CustomNumberEditor(BigInteger.class, false));
}


但是,並非Bean的屬性都是這些常見的類型,如果你的Bean需要注入一個自定義類型的屬性,而又想享受IoC的好處,那麼就只得自己開幹,提供一個自定義的PropertyEditor了。
下面,分幾個步驟來說明,定義一個自定義PropertyEditor的過程。
1)首先,碰到的問題即是,要如何編輯自己的PropertyEditor,其實需要了解一點java.beans包的知識,在該包中,有一個java.beans.PropertyEditor的接口,它定義了一套接口方法(12個),即通過這些方法如何將一個String變成內部的一個對象,這兩個方法是比較重要的:
a)setValue(Object value) 直接設置一個對象,一般不直接用該方法設置屬性對象
b)setAsText(String text) 通過一個字符串來構造對象,一般在此方法中解析字符串,將構造一個
類對象,調用setValue(Object)來完成屬性對象設置操作。

2)實現所有的接口方法是麻煩的,java.beans.PropertyEditorSupport 適時登場,一般情況下,我們通過擴展這個方便類即可。

3)編寫完後,就是在Spring配置文件中註冊該屬性類型編輯器的問題,Spring提供了專門的註冊工具類
org.springframework.beans.factory.config.CustomEditorConfigurer,它負責將屬性類型和
屬性編輯器關聯起來。到時BeanFactory注入Bean的屬性時,即會在註冊表中查找屬性類型對應的編輯器。

下面給出一個小例子,例子先作一個簡單描述:
1)Person 需要進行屬性注入的Bean,有兩個屬性 一個是name,一個是address Address是一個類
2)Address Person的屬性類型,本身有3個屬性。
3)AddressPropertyEditor Address類型對應的屬性編輯器。

開工:
1.Person.java


代碼
package com.stamen.propedit;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Person {
private String name;

private Address address;

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}


2.Address.java

代碼
package com.stamen.propedit;
import org.apache.commons.lang.builder.ToStringBuilder;
public class Address {
private String street;

private String doorNum;

private String postCode;

public String getDoorNum() {
return doorNum;
}

public void setDoorNum(String doorNum) {
this.doorNum = doorNum;
}

public String getPostCode() {
return postCode;
}

public void setPostCode(String postCode) {
this.postCode = postCode;
}

public String getStreet() {
return street;
}

public void setStreet(String street) {
this.street = street;
}

public String toString() {
return ToStringBuilder.reflectionToString(this);
}

}



AddressPropertyEditor.java

代碼
package com.stamen.propedit;

import java.beans.PropertyEditorSupport;
import java.util.Date;

import org.springframework.util.StringUtils;
public class AddressPropertyEditor extends PropertyEditorSupport{
//支持的格式爲 streeValue,doorNumValue,postCode
public void setAsText(String text)
{
System.out.println("使用自己的編輯器。");
if (text == null || !StringUtils.hasText(text)) {
throw new IllegalArgumentException("老大,不能爲空啊!");
}
else
{
String[] strArr = StringUtils.tokenizeToStringArray(text,",");
Address add = new Address();
add.setStreet(strArr[0]);
add.setDoorNum(strArr[1]);
add.setPostCode(strArr[2]);
setValue(add);
}
}

public String getAsText()
{
Address add = (Address)getValue();
return ""+add;
}
}



打開Spring配置文件,添上這兩個配置項:


代碼
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.stamen.propedit.Address"> <!-- 屬性類型 -->
<bean class="com.stamen.propedit.AddressPropertyEditor"/> <!--對應Address的編輯器 -->
</entry>
</map>
</property>
</bean>

<bean id="person" class="com.stamen.propedit.Person">
<property name="name" value="Tom"/>
<property name="address" value="朝陽區,Soho 1601,010101"/>
</bean>
發佈了15 篇原創文章 · 獲贊 0 · 訪問量 2934
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章