淺談Spring的屬性編輯器的使用
在 Spring 配置文件中,我們往往通過(guò)字面值設(shè)置 Bean 各種類型的屬性值 ,這個(gè)功能是通過(guò)屬性編輯器實(shí)現(xiàn)的。
任何實(shí)現(xiàn)了 java.beans.PropertyEditor 接口的類都是屬性編輯器 。 它可以將外部需要設(shè)置的值轉(zhuǎn)換為 JVM 內(nèi)部的對(duì)應(yīng)類型,所以屬性編輯器其實(shí)就是一個(gè)類型轉(zhuǎn)換器 。
1 JavaBean 編輯器
Sun 所制定的 JavaBean 編輯器,很大程度上是為 IDE 準(zhǔn)備的。它讓 IDE 能夠以可視化的方式來(lái)設(shè)置 JavaBean 的屬性 。
Java 通過(guò) java.beans.PropertyEditor 定義了設(shè)置 JavaBean 屬性的方法,通過(guò) BeanInfo 描述了 JavaBean 哪些屬性是可定制的,此外還描述了可定制屬性與 PropertyEditor 之間的對(duì)應(yīng)關(guān)系 。
BeanInfo 與 JavaBean 之間的對(duì)應(yīng)關(guān)系,通過(guò)兩者之間規(guī)范的命名確立,對(duì)應(yīng) JavaBean 的 BeanInfo 采用如下命名規(guī)范:<Bean>BeanInfo。 如 BookBean 對(duì)應(yīng)的 BeanInfo 為 BookBeanBeanInfo。 當(dāng) JavaBean 連同其屬性編輯器注冊(cè)到 IDE 后,當(dāng)在開(kāi)發(fā)界面中對(duì) JavaBean 進(jìn)行定制時(shí), IDE 就會(huì)根據(jù) JavaBean 規(guī)范找到對(duì)應(yīng)的 BeanInfo ,然后再根據(jù) BeanInfo 中的描述信息找到 JavaBean 屬性描述(使用哪個(gè)屬性編輯器等),進(jìn)而為 JavaBean 生成特定開(kāi)發(fā)編輯界面 。
Java 提供了一個(gè)用于管理默認(rèn)屬性編輯器的管理器: PropertyEditorManager ,它保存著一些常見(jiàn)類型的屬性編輯器,如果某個(gè) JavaBean 的常見(jiàn)類型屬性沒(méi)有通過(guò) BeanInfo 顯式指定它的屬性編輯器, 那么 IDE 將自動(dòng)使用 PropertyEditorManager 中注冊(cè)的對(duì)應(yīng)屬性的默認(rèn)編輯器 。
1.1 屬性編輯器(PropertyEditor)
PropertyEditor 是屬性編輯器接口,它定義了將外部設(shè)置值轉(zhuǎn)換為內(nèi)部 JavaBean 屬性值的接口方法 。主要接口方法說(shuō)明如下:
| 方法 | 說(shuō)明 |
|---|---|
| Object getValue() | 返回屬性的當(dāng)前值 ,基本類型被封裝成對(duì)應(yīng)的包裝類型 |
| void setValue(Object newValue) | 設(shè)置屬性的值,基本類型以包裝類型傳入 |
| String getAsText() | 用字符串來(lái)表示屬性對(duì)象,以便外部的屬性編輯器能夠以可視化的方式顯示 。 默認(rèn)返回 null ,表示該屬性不能以字符串表示。 |
| void setAsText(String text) | 用一個(gè)字符串去更新屬性的內(nèi)部值,它一般從外部屬性編輯器傳入的。 |
| String[] getTags() | 返回表示有效屬性值的字符串?dāng)?shù)組,以便屬性編輯器能夠以下拉框的方式進(jìn)行展示 。 默認(rèn)返回 null。 |
| String getJavaInitializationString() | 為屬性提供初始值,屬性編輯器以此值作為屬性的默認(rèn)值 。 |
PropertyEditor 接口是內(nèi)部屬性值和外部設(shè)置值的溝通橋梁 。
Java 為 PropertyEditor 提供了一個(gè)方便的實(shí)現(xiàn)類: PropertyEditorSupport ,該類實(shí)現(xiàn)了 PropertyEditor 接口,我們可以通過(guò)擴(kuò)展這個(gè)類來(lái)設(shè)計(jì)自己的屬性編輯器 。
1.2 Bean 屬性描述(BeanInfo)
BeanInfo 描述了 JavaBean 中的可編輯屬性以及對(duì)應(yīng)的屬性編輯器,每一個(gè)屬性對(duì)應(yīng)一個(gè)屬性描述器 PropertyDescriptor。
PropertyDescriptor 的構(gòu)造函數(shù)有兩個(gè)入?yún)ⅲ?PropertyDescriptor(String propertyName, Class beanClass) ,其中 propertyName 為屬性名; beanClass 是 JavaBean 所對(duì)應(yīng)的 Class。
PropertyDescriptor 還有一個(gè) setPropertyEditorClass(Class propertyEditorClass) 方法,它可以為 JavaBean 屬性指定編輯器 。
BeanInfo 接口中最重要的方法是:PropertyDescriptor[] getPropertyDescriptors() ,它會(huì)返回 JavaBean 的屬性描述器數(shù)組 。
BeanInfo 接口的一個(gè)常用的實(shí)現(xiàn)類是 SimpleBeanInfo ,我們可以通過(guò)擴(kuò)展這個(gè)類來(lái)實(shí)現(xiàn)自定義的功能 。
2 Spring 默認(rèn)屬性編輯器
Spring 的屬性編輯器與傳統(tǒng)的用于 IDE 開(kāi)發(fā)的屬性編輯器不同,它沒(méi)有 UI 界面,只是將配置文件中的文本配置值轉(zhuǎn)換為 Bean 屬性的對(duì)應(yīng)值 。
Spring 在 PropertyEditorRegistrySupport 中為常見(jiàn)的屬性類型提供了默認(rèn)屬性編輯器,分為 3 大類,共有 32 個(gè):
| 類型 | 說(shuō)明 |
|---|---|
| 基礎(chǔ)數(shù)據(jù)類型 | 【1】基本數(shù)據(jù)類型,如: boolean、int 等; 【2】基本數(shù)據(jù)類型封裝類,如: Boolean、Integer 等; 【3】基本數(shù)據(jù)類型數(shù)組: char[] 和 byte[] ; 【4】大數(shù): BigDecimal 和 BigInteger 。 |
| 集合類 | Collection、Set、SortedSet、List 和 SortedMap。 |
| 資源類 | Class、Class[]、File、InputStream、Locale、Properties、Resource[] 和 URL。 |
PropertyEditorRegistrySupport 中有兩個(gè)用于保存屬性編輯器的 Map 類型變量:
| 變量名 | 說(shuō)明 |
|---|---|
| defaultEditors | 保存默認(rèn)屬性類型的編輯器,元素的鍵為屬性類型,值為對(duì)應(yīng)的屬性編輯器實(shí)例。 |
| customEditors | 保存用戶自定義的屬性編輯器,元素的鍵值和 defaultEditors 相同 。 |
3 自定義 Spring 屬性編輯器
如果我們的應(yīng)用定義了特殊類型的屬性,并且希望在配置文件中以字面值方式來(lái)配置屬性值,那么就可以編寫(xiě)自定義屬性編輯器并注冊(cè)到 Spring 容器的方式來(lái)實(shí)現(xiàn)。
Spring 默認(rèn)的屬性編輯器大都擴(kuò)展自 java.beans.PropertyEditorSupport,我們可以通過(guò)擴(kuò)展 PropertyEditorSupport 來(lái)自定義屬性編輯器 。在Spring 環(huán)境下僅需要將配置文件中字面值轉(zhuǎn)換為屬性類型的對(duì)象即可,并不需要提供 UI 界面,所以僅需要覆蓋 PropertyEditorSupport 的 setAsText() 方法就可以啦 (∩_∩)O哈哈~。
假設(shè)我們有兩個(gè)實(shí)體 Book 和 Author,希望在配置 Book 時(shí),可以直接設(shè)置 Author 的名字。
Book.java
public class Book {
/**
* 作者
*/
private Author author;
/**
* 書(shū)名
*/
private String name;
//省略 get/setter 方法
}
Author.java
public class Author {
private String name;
//省略 get/setter 方法
}
首先,自定義 author 的屬性編輯器:
public class CustomPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if(text==null||text.length()==0){
throw new IllegalArgumentException("格式錯(cuò)誤");
}
Author author=new Author();
author.setName(text);
//調(diào)用父類的方法,來(lái)設(shè)置屬性對(duì)象
setValue(author);
}
}
如果使用 BeanFactory ,則需要手工調(diào)用 registerCustomEditor(Class requiredType, PropertyEditor propertyEditor) 方法注冊(cè)自定義屬性編輯器;如果使用的是 ApplicationContext ,那么只需要在配置文件中注冊(cè) CustomEditorConfigurer 即可 。CustomEditorConfigurer 實(shí)現(xiàn)了BeanFactoryPostProcessor 接口,所以它是一個(gè) Bean 的工廠后處理器 。
現(xiàn)在注冊(cè)自定義的屬性編輯器:
<!-- 注冊(cè)自定義的屬性編輯器-->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<!-- key:屬性類型;value:屬性編輯器-->
<entry key="net.deniro.spring4.editor.Author"
value="net.deniro.spring4.editor.CustomPropertyEditor"
/>
</map>
</property>
</bean>
<bean id="book" class="net.deniro.spring4.editor.Book">
<property name="name" value="海邊的卡夫卡"/>
<!-- 使用之前定義的編輯器注入該屬性-->
<property name="author" value="村上春樹(shù)"/>
</bean>
BeanWrapper 在設(shè)置 book 的 author 屬性時(shí),將檢索自定義屬性編輯器注冊(cè)表,當(dāng)發(fā)現(xiàn) author 屬性類型所對(duì)應(yīng)的屬性編輯器 CustomPropertyEditor 時(shí),它就會(huì)這個(gè)定制的屬性編輯器把 "村上春樹(shù)" 轉(zhuǎn)換為 Author 對(duì)象 。
按照規(guī)范, Java 會(huì)在 JavaBean 的相同類包下查找是否存在 <JavaBean>Editor 的類;如果存在,就會(huì)自動(dòng)使用 <JavaBean>Editor作為該 JavaBean 的屬性編輯器 。Spring 也支持這個(gè)規(guī)范。
所以如果在類包下有一個(gè)名為 AuthorEditor 屬性編輯器類,那么就無(wú)須在配置文件中注冊(cè)自定義的屬性編輯器啦O(∩_∩)O哈哈~
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springboot 使用QQ郵箱發(fā)送郵件的操作方法
這篇文章主要介紹了springboot使用QQ郵箱發(fā)送郵件功能,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10
quartz實(shí)現(xiàn)定時(shí)功能實(shí)例詳解(servlet定時(shí)器配置方法)
Quartz是一個(gè)完全由java編寫(xiě)的開(kāi)源作業(yè)調(diào)度框架,下面提供一個(gè)小例子供大家參考,還有在servlet配置的方法2013-12-12
java實(shí)現(xiàn)遺傳算法實(shí)例分享(打印城市信息)
本文介紹java實(shí)現(xiàn)遺傳算法的實(shí)例,代碼中使用城市名做為數(shù)據(jù),可以打印當(dāng)前代數(shù)的所有城市序列,以及其相關(guān)的參數(shù),大家參考使用吧2014-01-01
Java在高并發(fā)場(chǎng)景下實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器
點(diǎn)贊計(jì)數(shù)器的本質(zhì)就是對(duì)某個(gè)變量在高并發(fā)情況下的修改,這篇文章主要為大家介紹了Java實(shí)現(xiàn)點(diǎn)贊計(jì)數(shù)器的示例代碼,感興趣的小伙伴可以了解一下2023-06-06
ehcache開(kāi)源緩存框架_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Ehcache是現(xiàn)在最流行的純Java開(kāi)源緩存框架,這篇文章主要介紹了ehcache框架的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Springboot+Poi導(dǎo)入Excel表格實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了Springboot+Poi導(dǎo)入Excel表格實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Java?SpringBoot?獲取接口實(shí)現(xiàn)類匯總
這篇文章主要介紹了Java?SpringBoot?獲取接口實(shí)現(xiàn)類匯總,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
druid執(zhí)行SQL出現(xiàn)錯(cuò)誤但不影響返回結(jié)果的問(wèn)題及解決
這篇文章主要介紹了druid執(zhí)行SQL出現(xiàn)錯(cuò)誤但不影響返回結(jié)果的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12

