基于JavaBean編輯器讀取peroperties文件的實(shí)例
引言
最近在重讀《精通Spring+4.x++企業(yè)應(yīng)用開(kāi)發(fā)實(shí)戰(zhàn)》這本書(shū),看到了有關(guān)JavaBean編輯器的部分,了解到PropertyEditor和BeanInfo的使用。不得不說(shuō),BeanInfo是一個(gè)很強(qiáng)大的東西,Java中的內(nèi)省也與之有一點(diǎn)點(diǎn)小關(guān)聯(lián)。
JavaBean、PropertyEditor與BeanInfo
JavaBean簡(jiǎn)單介紹
JavaBean是一種Java寫(xiě)成的可重用組件,本質(zhì)上還是一個(gè)Java類(lèi),但是與一般的Java類(lèi)不同,JavaBean必須有一個(gè)無(wú)參的構(gòu)造函數(shù),其字段必須私有化,并提供set、get方法供外界使用。根據(jù)書(shū)中所介紹,Sun所制定的JavaBean規(guī)范很大程度山是為了IDE準(zhǔn)備的--它讓IDE能夠以可視化的方式設(shè)置JavaBean的屬性。
PropertyEditor接口
PropertyEditor是屬性編輯器的接口,其作用是將一個(gè)String類(lèi)型的值轉(zhuǎn)換為JavaBean的屬性。Java為PropertyEditor提供了一個(gè)默認(rèn)的實(shí)現(xiàn)類(lèi)PropertyEditorSupport。
BeanInfo接口
BeanInfo用于描述JavaBean哪些屬性可以編輯及對(duì)應(yīng)屬性編輯器。Java為BeanInfo也提供了一個(gè)默認(rèn)實(shí)現(xiàn)--SimpleBeanInfo。
其他
更多有關(guān)JavaBean以及這兩個(gè)接口的知識(shí),可以購(gòu)買(mǎi)這本書(shū)《精通Spring+4.x++企業(yè)應(yīng)用開(kāi)發(fā)實(shí)戰(zhàn)》,或者看我的Copy
一個(gè)小例子
在《精通Spring+4.x++企業(yè)應(yīng)用開(kāi)發(fā)實(shí)戰(zhàn)》中使用的例子是根據(jù)《Core Java II》的一個(gè)例子改變而成,但是有一個(gè)小缺點(diǎn),該例子使用到了Swing,演示時(shí)需要將代碼打成JAR包,使用IDE組件擴(kuò)展管理功能注冊(cè)到IDE中,不太方便,因此我特意嘗試用JavaBean編輯器讀取properties文件作為一個(gè)小例子。
定義一個(gè)JavaBean
我們先定義一個(gè)Person類(lèi),用作JavaBean
/**
* 一個(gè)簡(jiǎn)單的JavaBean
* @author aming
*
*/
public class Person implements Serializable {
private static final long serialVersionUID = 6366021085463785872L;
/**
* 姓名
*/
private String name;
/**
* 年齡
*/
private int age;
/**
* 性別
*/
private Gender gender;
/**
* 生日
*/
private Date birthday;
/**
* 是否結(jié)婚
*/
private boolean married;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public boolean isMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + gender + ", birthday=" + birthday + ", married="
+ married + "]";
}
}
其中Gender是我自定義的枚舉,其代碼如下:
/**
* 表示性別的枚舉類(lèi)
* @author aming
*
*/
public enum Gender {
M(1,"男"),F(2,"女");
private int id;
private String genderName;
public String getGenderName() {
return genderName;
}
Gender(int id,String genderName){
this.id = id;
this.genderName = genderName;
}
public static Gender getGender(int id) {
for(Gender gender:values()) {
if(gender.id == id) {
return gender;
}
}
return M;
}
public static Gender getGender(String genderName) {
for(Gender gender:values()) {
if(gender.genderName == genderName) {
return gender;
}
}
return M;
}
}
實(shí)現(xiàn)PropertyEditor
Person類(lèi)中有5個(gè)字段,分別使用String、int、Gender、Date和boolean這5中類(lèi)型,其中對(duì)String類(lèi)型變量name我們使用PropertyEditorSupport這個(gè)默認(rèn)實(shí)現(xiàn)就可以了,其他的類(lèi)型我們需要自定義去實(shí)現(xiàn)PropertyEditor接口--int對(duì)應(yīng)IntegerPropertyEditor、Gender對(duì)應(yīng)GenderPropertyEditor、Date對(duì)應(yīng)DatePropertyEditor以及boolean對(duì)應(yīng)BooleanPropertyEditor。
IntegerPropertyEditor
IntegerPropertyEditor類(lèi)繼承了PropertyEditorSupport類(lèi)和實(shí)現(xiàn)PropertyEditor接口(個(gè)人習(xí)慣實(shí)現(xiàn)接口的時(shí)候同時(shí)繼承一個(gè)默認(rèn)實(shí)現(xiàn),這樣我可以只關(guān)心我所需要實(shí)現(xiàn)的方法,當(dāng)然,這個(gè)默認(rèn)實(shí)現(xiàn)最好是一個(gè)抽象類(lèi)),重寫(xiě)了getAsText()方法和setAsText(String text),其代碼如下:
@Override
public String getAsText() {
return String.valueOf((int)getValue());
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
try {
setValue(Integer.parseInt(text));
} catch(NumberFormatException e) {
throw new IllegalArgumentException(e);
}
}
GenderPropertyEditor
GenderPropertyEditor主要是將外部獲得到的字符串去轉(zhuǎn)換為Gender,其實(shí)現(xiàn)思路是,先嘗試將該字符串轉(zhuǎn)換為Integer類(lèi)型,如果轉(zhuǎn)換成功則將轉(zhuǎn)換得到Integer值通過(guò)Gender枚舉的靜態(tài)方法getGender(int id)獲取Gender類(lèi)型的變量;如果轉(zhuǎn)換失敗,則將該字符串看作genderName,再去獲取Gender。至于Gender到字符串,直接返回genderName就可以了。主要代碼如下:
@Override
public String getAsText() {
Gender value = (Gender)getValue();
return value.getGenderName();
}
@Override
public void setAsText(String value) throws IllegalArgumentException {
try {
setValue(Gender.getGender(Integer.valueOf(value)));
}catch(NumberFormatException ex) {
setValue(Gender.getGender(value));
}
}
DatePropertyEditor
DatePropertyEditor的思路和GenderPropertyEditor相似,其核心代碼獻(xiàn)上:
private DateFormat df;
@Override
public String getAsText() {
Date date = (Date)getValue();
return df.format(date);
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
try {
setValue(df.parse(text));
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}
public DatePropertyEditor() {
super();
this.df = new SimpleDateFormat("yyyy-MM-dd");
}
BooleanPropertyEditor
BooleanPropertyEditor與IntegerPropertyEditor一樣,實(shí)現(xiàn)非常類(lèi)似:
@Override
public String getAsText() {
return String.valueOf((boolean)getValue());
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(Boolean.valueOf(text));
}
自定義BeanInfo
定義PersonBeanInfo類(lèi),用于描述Person屬性和相對(duì)應(yīng)的PropertyEditor。代碼如下:
public class PersonBeanInfo extends SimpleBeanInfo implements BeanInfo {
@Override
public PropertyDescriptor[] getPropertyDescriptors() {
List<PropertyDescriptor> list = new ArrayList<>();
try {
// 將Person中name與PropertyEditorSupport綁定
PropertyDescriptor namePropertyDescriptor = new PropertyDescriptor("name",Person.class);
namePropertyDescriptor.setPropertyEditorClass(PropertyEditorSupport.class);
// 將Person中age與IntegerPropertyEditor綁定
PropertyDescriptor agePropertyDescriptor = new PropertyDescriptor("age",Person.class);
agePropertyDescriptor.setPropertyEditorClass(IntegerPropertyEditor.class);
// 將Person中g(shù)ender與GenderPropertyEditor綁定
PropertyDescriptor genderPropertyDescriptor = new PropertyDescriptor("gender", Person.class);
genderPropertyDescriptor.setPropertyEditorClass(GenderPropertyEditor.class);
// 將Person中birthday與DatePropertyEditor綁定
PropertyDescriptor birthdayPropertyDescriptor = new PropertyDescriptor("birthday",Person.class);
birthdayPropertyDescriptor.setPropertyEditorClass(DatePropertyEditor.class);
// 將Person中married與BooleanPropertyEditor綁定
PropertyDescriptor marriedPropertyDescriptor = new PropertyDescriptor("married",Person.class);
marriedPropertyDescriptor.setPropertyEditorClass(BooleanPropertyEditor.class);
list.add(namePropertyDescriptor);
list.add(agePropertyDescriptor);
list.add(genderPropertyDescriptor);
list.add(birthdayPropertyDescriptor);
list.add(marriedPropertyDescriptor);
return list.toArray(new PropertyDescriptor[list.size()]);
} catch (IntrospectionException ex) {
ex.printStackTrace();
}
return null;
}
}
創(chuàng)建配置文件
因?yàn)槲覄?chuàng)建的是一個(gè)普通的Java項(xiàng)目,因此我選擇在src目錄下創(chuàng)建person.properites文件,文件內(nèi)容如下:
name=arthurming age=18 gender=1 birthday=2017-10-24 married=true
測(cè)試
測(cè)試代碼
@Test
public void test() throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Properties p = new Properties();
InputStream is =this.getClass().getClassLoader().getResourceAsStream("person.properties");
p.load(is);
BeanInfo beanInfo = new PersonBeanInfo();
PropertyDescriptor[] propertyDescriptoies = beanInfo.getPropertyDescriptors();
Person person = new Person();
for(PropertyDescriptor propertyDescriptor : propertyDescriptoies) {
String key = propertyDescriptor.getName();
String value = p.getProperty(key);
Method method = propertyDescriptor.getWriteMethod();
PropertyEditor pe = (PropertyEditor) propertyDescriptor.getPropertyEditorClass().newInstance();
if(pe.getClass() == PropertyEditorSupport.class) { //①
pe.setValue(value);
} else {
pe.setAsText(value);
}
method.invoke(person,pe.getValue());
}
System.out.println(person);
}
說(shuō)明:代碼①表示當(dāng)pe類(lèi)型是PropertyEditorSupport,而不是我所定義PropertyEdtior,應(yīng)該使用setValue方法而不是setAsText方法。
因?yàn)樵赑ropertyEditorSupport中,其setAsText()方法為:
public void setAsText(String text) throws java.lang.IllegalArgumentException {
if (value instanceof String) {
setValue(text);
return;
}
throw new java.lang.IllegalArgumentException(text);
}
如果使用setAsText()方法,那么由于value不是String類(lèi)型,將會(huì)拋出IllegalArgumentException。不過(guò)很遺憾我搞明白value到底實(shí)際上什么類(lèi)型......
測(cè)試結(jié)果
Person [name=arthurming, age=18, gender=M, birthday=Tue Oct 24 00:00:00 CST 2017, married=true]
小結(jié)
感覺(jué)您能容忍我拙劣的文筆看到現(xiàn)在,也希望你在讀《精通Spring+4.x++企業(yè)應(yīng)用開(kāi)發(fā)實(shí)戰(zhàn)》這本書(shū)時(shí),看到有關(guān)JavaBean編輯器的知識(shí),我的這個(gè)例子可以對(duì)你有所幫助。
以上這篇基于JavaBean編輯器讀取peroperties文件的實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Java Swing中JTable渲染器與編輯器用法示例
- Java Swing中的文本框(JTextField)與文本區(qū)(JTextArea)使用實(shí)例
- java實(shí)現(xiàn)文本框和文本區(qū)的輸入輸出
- 淺談java中文本框和文本區(qū)
- java微信企業(yè)號(hào)開(kāi)發(fā)之發(fā)送消息(文本、圖片、語(yǔ)音)
- Java Swing中的文本區(qū)(JTextArea)實(shí)現(xiàn)換行保存到文件的幾個(gè)方法
- JavaMail實(shí)現(xiàn)發(fā)送超文本(html)格式郵件的方法
- Java文本編輯器實(shí)現(xiàn)方法詳解
相關(guān)文章
idea如何快速查找一個(gè)類(lèi)或類(lèi)中方法名和變量
這篇文章主要介紹了idea如何快速查找一個(gè)類(lèi)或類(lèi)中方法名和變量問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
SpringSecurity如何實(shí)現(xiàn)配置單個(gè)HttpSecurity
這篇文章主要介紹了SpringSecurity如何實(shí)現(xiàn)配置單個(gè)HttpSecurity,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
JAVA 文件監(jiān)控 WatchService的示例方法
本篇文章主要介紹了JAVA 文件監(jiān)控 WatchService的示例方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Java實(shí)現(xiàn)經(jīng)典拳皇誤闖冒險(xiǎn)島游戲的示例代碼
《拳皇誤闖冒險(xiǎn)島》是拳皇和冒險(xiǎn)島素材的基于JavaSwing的動(dòng)作類(lèi)游戲。本文將用Java語(yǔ)言實(shí)現(xiàn)這一游戲,需要的小伙伴可以參考一下2022-02-02
SpringBoot如何動(dòng)態(tài)修改Scheduled(系統(tǒng)啟動(dòng)默認(rèn)執(zhí)行,動(dòng)態(tài)修改)
這篇文章主要介紹了SpringBoot如何動(dòng)態(tài)修改Scheduled(系統(tǒng)啟動(dòng)默認(rèn)執(zhí)行,動(dòng)態(tài)修改)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java并發(fā)之Semaphore工具類(lèi)r的全面解析
Semaphore 是 java.util.concurrent中非常有用的并發(fā)編程工具類(lèi),它通常被用于限制對(duì)某個(gè)資源或資源池的并發(fā)訪問(wèn)數(shù)量,下面我們就來(lái)深入了解一下Semaphore的具體使用吧2024-02-02
解決IDEA上循環(huán)依賴(lài)報(bào)錯(cuò)問(wèn)題Error:java: Annotation processing&n
這篇文章主要介紹了解決IDEA上循環(huán)依賴(lài)報(bào)錯(cuò)問(wèn)題Error:java: Annotation processing is not supported for module cycles,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2023-10-10

