您好,登錄后才能下訂單哦!
引言
最近在重讀《精通Spring+4.x++企業應用開發實戰》這本書,看到了有關JavaBean編輯器的部分,了解到PropertyEditor和BeanInfo的使用。不得不說,BeanInfo是一個很強大的東西,Java中的內省也與之有一點點小關聯。
JavaBean、PropertyEditor與BeanInfo
JavaBean簡單介紹
JavaBean是一種Java寫成的可重用組件,本質上還是一個Java類,但是與一般的Java類不同,JavaBean必須有一個無參的構造函數,其字段必須私有化,并提供set、get方法供外界使用。根據書中所介紹,Sun所制定的JavaBean規范很大程度山是為了IDE準備的--它讓IDE能夠以可視化的方式設置JavaBean的屬性。
PropertyEditor接口
PropertyEditor是屬性編輯器的接口,其作用是將一個String類型的值轉換為JavaBean的屬性。Java為PropertyEditor提供了一個默認的實現類PropertyEditorSupport。
BeanInfo接口
BeanInfo用于描述JavaBean哪些屬性可以編輯及對應屬性編輯器。Java為BeanInfo也提供了一個默認實現--SimpleBeanInfo。
其他
更多有關JavaBean以及這兩個接口的知識,可以購買這本書《精通Spring+4.x++企業應用開發實戰》,或者看我的Copy
一個小例子
在《精通Spring+4.x++企業應用開發實戰》中使用的例子是根據《Core Java II》的一個例子改變而成,但是有一個小缺點,該例子使用到了Swing,演示時需要將代碼打成JAR包,使用IDE組件擴展管理功能注冊到IDE中,不太方便,因此我特意嘗試用JavaBean編輯器讀取properties文件作為一個小例子。
定義一個JavaBean
我們先定義一個Person類,用作JavaBean
/** * 一個簡單的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; /** * 是否結婚 */ 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是我自定義的枚舉,其代碼如下:
/** * 表示性別的枚舉類 * @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; } }
實現PropertyEditor
Person類中有5個字段,分別使用String、int、Gender、Date和boolean這5中類型,其中對String類型變量name我們使用PropertyEditorSupport這個默認實現就可以了,其他的類型我們需要自定義去實現PropertyEditor接口--int對應IntegerPropertyEditor、Gender對應GenderPropertyEditor、Date對應DatePropertyEditor以及boolean對應BooleanPropertyEditor。
IntegerPropertyEditor
IntegerPropertyEditor類繼承了PropertyEditorSupport類和實現PropertyEditor接口(個人習慣實現接口的時候同時繼承一個默認實現,這樣我可以只關心我所需要實現的方法,當然,這個默認實現最好是一個抽象類),重寫了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主要是將外部獲得到的字符串去轉換為Gender,其實現思路是,先嘗試將該字符串轉換為Integer類型,如果轉換成功則將轉換得到Integer值通過Gender枚舉的靜態方法getGender(int id)獲取Gender類型的變量;如果轉換失敗,則將該字符串看作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相似,其核心代碼獻上:
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一樣,實現非常類似:
@Override public String getAsText() { return String.valueOf((boolean)getValue()); } @Override public void setAsText(String text) throws IllegalArgumentException { setValue(Boolean.valueOf(text)); }
自定義BeanInfo
定義PersonBeanInfo類,用于描述Person屬性和相對應的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中gender與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; } }
創建配置文件
因為我創建的是一個普通的Java項目,因此我選擇在src目錄下創建person.properites文件,文件內容如下:
name=arthurming age=18 gender=1 birthday=2017-10-24 married=true
測試
測試代碼
@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); }
說明:代碼①表示當pe類型是PropertyEditorSupport,而不是我所定義PropertyEdtior,應該使用setValue方法而不是setAsText方法。
因為在PropertyEditorSupport中,其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類型,將會拋出IllegalArgumentException。不過很遺憾我搞明白value到底實際上什么類型......
測試結果
Person [name=arthurming, age=18, gender=M, birthday=Tue Oct 24 00:00:00 CST 2017, married=true]
小結
感覺您能容忍我拙劣的文筆看到現在,也希望你在讀《精通Spring+4.x++企業應用開發實戰》這本書時,看到有關JavaBean編輯器的知識,我的這個例子可以對你有所幫助。
以上這篇基于JavaBean編輯器讀取peroperties文件的實例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。