Apache的BeanUtils包提供萬能類DynaBean,使用此類可以不必創建大量的VO,Form等僅僅用來傳值的對象。
BeanUtils 通過三個類來實現此功能,DynaBean,DynaClass,DynaProperty,我從網上搜到一片文章,有一
段講的很詳細,引用過來共同學習:
DynaBean並不是Java中所定義的Bean,而是一種“假”的Bean。因爲它並不是通過getXXX和setXXX方法,對XXX屬性進行取值和設值的。它通過一個實現了DynaClass接口的類,幫助管理其所有的屬性的類別,而自己則管理對XXX屬性值的設定和獲取。在設值的時候會通過與name對應的DynaProperty對象,檢查賦值的類別是否正確。
DynaProperty類描述的是DynaBean中所包含的屬性的類型。DynaProperty類有三個屬性:屬性的名稱:name,屬性的名稱;type,屬性的類別;contentType,如果DynaProperty描述的是個容器對象(List或者Map),那麼這個contentType就代表這個容器內元素的類別。這個類值得關注的地方是writeObject和readObject方法的實現。它會首先判斷自己的type是否是一個primitive的類,如果是,則先寫入true標誌,再寫入對應的primitive類的編號;否則寫入false標誌,再寫入type。因爲在調用readObject方法時,如果得出的是primitive類型,則type的值爲XXX.TYPE而不是XXX.class。
DynaClass 是一個接口,用來管理DynaBean中所有的DynaProperty屬性。
二、BasiceDyanBean 與 BasicDynaClass
BasiceDyanBean 實現自DynaBean接口。它包含一個實現了DynaClass接口的類的對象,和一個用來存放值的HashMap。這個HashMap的key與DynaClass中HashMap的key是一一對應的。
BasicDynaClass 實現了DynaClass接口,以DynaProperty的name爲key保存所有這些DynaProperty對象。它通過newInstance方法動態生成實現了DynaBean接口的類的對象;注意這個類是可以動態指定的,如果沒有,那麼就是默認的BasicDynaBean類。動態指定類是通過反射實現的,程序如下:
//dynaBeanClass爲任意的實現了DynaBean接口的類,constructorTypes爲這個
//類的構造方法所需要的參數的類型
constructor = dynaBeanClass.getConstructor(constructorTypes);
//constructorValues爲構造方法的參數值,實際上它的值爲當前的BasicDynaClass
return ((DynaBean) constructor.newInstance(constructorValues));
下面通過實例來講解用法
1.首先創建DynaProperty用來表示屬性對象(此類沒有子類沒有父類)
此類有三種構造方法:
①. DynaProperty(String name): name屬性名,默認屬性爲Object;
②.DynaProperty(String name, Class type) 不用解釋type爲屬性類型;
③.DynaProperty(String name, Class type, Class contentType) 此類主要用來創建List或Map屬性,contentType參數指List或Map存儲值的類型;
2.構造DynaClass類,管理所有屬性的類,一起看看構造器吧
①BasicDynaClass() 自己通過set器初始化;
②BasicDynaClass(String name, Class dynaBeanClass) 如果你傳遞的不是LazyDynaBean
③BasicDynaClass(String name, Class dynaBeanClass, DynaProperty[] properties)建議使用這個,
name:bean名稱,dynaBeanClass:DynaBean類,properties:傳遞我們第一步創建的props;
- BasicDynaClass dynaClass=new BasicDynaClass("user",BasicDynaBean.class,props);
3.實例化DynaBean
- DynaBean dynaBean = dynaClass.newInstance();
- SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
- dynaBean.set("name", "章子怡");
- dynaBean.set("age", 16);
- dynaBean.set("birth", sdf.parse("1986-05-01"));
- StringBuilder sb=new StringBuilder();
- sb.append("name:").append(dynaBean.get("name"))
- .append(",age:").append(dynaBean.get("age"))
- .append(",birth:").append(sdf.format(dynaBean.get("birth")));
- System.out.println(sb.toString());
OK,大功告成,當然,如果你想使用延遲加載屬性,你可以傳遞LazyDynaBean作爲BasicDynaClass的參數,關於LazyDynaBean系列後續再一起探討吧