幾種封裝javaBean的方法
開發架構時,經常需要使用java對象(javaBean)的屬性來封裝程式的資料,封裝javaBean的方法有很多,比如反射,內省,以及使用工具類。下面從反射開始介紹。
1.javaBean介紹:簡介:
JavaBean是使用Java語言開發的一個可重用的組件,在開發中可以使用JavaBean減少重複代碼,使整個代碼的開發更簡潔。
編寫要求:
javaBean本身是一個類,設計該類的時候要遵循一下方法:
1.如果成員變數的名字是xxx,則相應地有兩個用來得到成員變數值和設定變數值的方法,它們分別是getXxx()和setXxx()且是public的: public datatype getXxx(); public void setXxx(datatype data);(2)如果成員變數是boolean型資料,使用is代替get方法;: public boolean isXxx();(3)需要一個無參數的建構函式。
一個javaBean的例子:
//javaBeanpublic class Person { private int id; private String name; public Person(int id, String name) { super(); this.id = id; this.name = name; } //無參數建構函式 public Person(){} //獲得Id屬性 public int getId() { return id; } //設定 public void setId(int id) { this.id = id; } //get方法 public String getName() { return name; } public void setName(String name) { this.name = name; } //tostring不在要求之中; @Override public String toString() { return id:+ this.id+ name:+ this.name; }}
2.使用反射封裝JavaBean:
通過反射更改對象域來封裝JavaBean,通過getDeclaredField方法獲得對應的域,並調用set方法進行修改。
下面的方法通過設定檔更改JavaBean的屬性:
設定檔內容如下:obj.txtcom.rlovep.bean.Personid=22name=peace代碼與注釋:public class CofigRef { public static void main(String[] args) { try { //獲得更改後的對象; Person p=(Person)getInstance(); System.out.println(p); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //根據設定檔的內容生產對象的對象並且要把對象的屬性值封裝到對象中。 public static Object getInstance() throws Exception{ //通過字元流進行輸入; BufferedReader bufferedReader = new BufferedReader(new FileReader(obj.txt)); String className = bufferedReader.readLine(); //讀取設定檔擷取到完整的類名。 Class clazz = Class.forName(className); //通過class對象擷取到無參的構造方法 Constructor constructor = clazz.getConstructor(null); //建立對象 Object o = constructor.newInstance(null); //讀取屬性值 String line = null; while((line = bufferedReader.readLine())!=null){ String[] datas = line.split(=); //通過屬性名稱擷取到對應的Field對象。 Field field = clazz.getDeclaredField(datas[0]); field.setAccessible(true); if(field.getType()==int.class){ //更改屬性內容; field.set(o, Integer.parseInt(datas[1])); }else{ field.set(o, datas[1]); } } bufferedReader.close(); return o; }
此去用反射變更,直接更改實現域的值;比較麻煩。需要各種判斷和操作,不適合用於開發。
3.通過內省封裝JavaBean:
內省(Introspector) 是Java 語言對 JavaBean 類屬性、事件的一種預設處理方法。Java JDK中提供了一套 API 用來訪問某個屬性的 getter/setter 方法,這就是內省。
1. PropertyDescriptor類:
屬性描述器類,利用該類可以獲得對應屬性的get和set方法。
getReadMethod(),獲得用於讀取屬性值的方法;getWriteMethod(),獲得用於寫入屬性值的方法;
示範如下:
//屬性描述器 PropertyDescriptor descriptor = new PropertyDescriptor(id, Person.class); //擷取屬性對應的get或者是set方法設定或者擷取屬性了。 Method m = descriptor.getWriteMethod(); //擷取屬性的set方法。 //執行該方法設定屬性值 m.invoke(p,110); //獲得get方法; Method readMethod = descriptor.getReadMethod(); //是擷取屬性的get方法 System.out.println(readMethod.invoke(p, null));
Introspector類:
通過調用Introspector.getBeanInfo(People.class)方法可以獲得BeanInfo對象,改對象封裝了people類的所有屬性。
而BeanInfo中有方法 getPropertyDescriptors(),獲得屬性的描述PropertyDescriptor[],可以通過遍曆返回結果可以操作JavaBean。示範如下:
//Introspector 內省類 BeanInfo beanInfo = Introspector.getBeanInfo(Person.class); //通過BeanInfo擷取所有的屬性描述 PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); //擷取一個類中的所有屬性描述器 for(PropertyDescriptor p : descriptors){ //獲得所有get方法 System.out.println(p.getReadMethod()); //get方法 }
通過這兩個類的比較可以看出,都是需要獲得PropertyDescriptor,只是方式不一樣:前者通過建立對象直接獲得,後者需要遍曆,所以使用PropertyDescriptor類更加方便。
內省封裝比反射相對來說簡單點,但是實質上是反射的一種變體。
4利用BeanUtils封裝JavaBean介紹:
每次都使用反射技術完成此類操作過於麻煩,所以Apache開發了一套簡單、易用的API來操作Bean的屬性–BeanUtils工具包。
注意:應用的時候還需要一個logging
BeanUtils:連結
logging:連結 使用BeanUtils:
BeanUtils主要解決 的問題: 把對象的屬性資料封裝 到對象中。
屬性值從設定檔中擷取時可能都是String類型, BeanUtils好處是如果屬性是基本資料 類型,BeanUtils會自動幫我轉換資料類型。如果設定的屬性是其他的引用 類型資料,這時候可以註冊一個類型轉換器。
1.獲得屬性的方法:BeanUtils.getProperty(admin,”userName”);
2.設定屬性的方法:BeanUtils.setProperty(admin, “id”, 001);
3.拷貝屬性的方法:BeanUtils.copyProperty(admin, “usetName”, “peace”);與set效果相同。
4.當屬性不能自動轉換通過ConvertUtils.register(new Converter())註冊轉換器; 示範如下:
需要引入包:commons-logging.jar 、 commons-beanutils-1.8.0.jar
Admin中的屬性:
private int id;private String userName;private String pwd;private int age;private Date birth;
BeanUtils使用如下:
public class BeanOpr { private String name; @Test /** * * @Title: testHello * @Description: beanutiils拷貝的介紹 * @return:void * @throws * @author peace w_peace@163.com */ public void testHello(){ Admin admin=new Admin(); try { //獲得屬性方法: System.out.println(BeanUtils.getProperty(admin,userName)); //拷貝屬性 BeanUtils.copyProperty(admin, usetName, peace); //類似於設定屬性 BeanUtils.setProperty(admin, id, 001); //對象的拷貝 Admin admin2=new Admin(); BeanUtils.copyProperties(admin2, admin); //輸出兩個admin System.out.println(admin); System.out.println(admin2); //map資料,拷貝到對象中 Map map=new HashMap<>(); map.put(userName,peace2); map.put(age, 22); map.put(id, 002); map.put(pwd, 123456); //通過Map拷貝: BeanUtils.populate(admin,map); System.out.println(admin); } catch (IllegalAccessException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * * @Title: testRegist * @Description: 實現對不支援的類進行轉換。 * @return:void * @throws * @author peace w_peace@163.com */ @Test public void testRegist(){ // 註冊日期類型轉換器:1, 自訂的方式 ConvertUtils.register(new Converter() { /** * 轉換函式,實現對date的轉換。 */ @Override public Object convert(Class type, Object value) { //判斷是否為Date類型 if(type!=Date.class) return null; //判斷是否為空白 if(value==null||.equals(value.toString().trim())) return null; try { //轉換方式 SimpleDateFormat date=new SimpleDateFormat(yyyy-mm-dd); return date.parse(value.toString()); } catch (ParseException e) { throw new RuntimeException(e); } } }, Date.class); //執行 Admin admin=new Admin(); Map map=new HashMap<>(); map.put(userName,peace2); map.put(age, 22); map.put(id, 002); map.put(pwd, 123456); map.put(birth, new Date(2015, 10, 9)); try { BeanUtils.populate(admin,map); System.out.println(admin); } catch (IllegalAccessException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Test /** * * @Title: testRigest2 * @Description: 使用提供的date類型轉換器 * @return:void * @throws * @author peace w_peace@163.com */ public void testRigest2(){ ConvertUtils.register(new DateConverter(), Date.class); //執行 Admin admin=new Admin(); Map map=new HashMap<>(); map.put(userName,peace2); map.put(age, 22); map.put(id, 002); map.put(pwd, 123456); map.put(birth, new Date(2015, 10, 9)); try { BeanUtils.populate(admin,map); System.out.println(admin); } catch (IllegalAccessException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
5.Dbutils資料庫JDBC專用工具也可以封裝JavaBean:
commons-dbutils 是 Apache 組織提供的一個開源 JDBC工具類庫,它是對JDBC的簡單封裝,學習成本極低,並且使用dbutils能極大簡化jdbc編碼的工作量,同時也不會影響程式的效能。
下載連結:連結
此去只是簡要介紹,後面jdbc教程中在做完整介紹使用如下:
@Test /** * * @Title: testQueryOne * @Description: 使用組件提供的結果集對象封裝資料。 * @return:void * @throws * @author peace w_peace@163.com */ public void testQueryOne(){ String sql=select * from admin where id=?; //擷取串連 connection=JdbcUtil.getConnection(); //建立Dbutils核心工具類 QueryRunner qr=new QueryRunner(); //查詢返回單個對象 try { //使用beanhandle進行封裝 //參數依次為:串連,sql語句,結果處理器,位置參數 //查下你結果封裝到Admin Admin admin=qr.query(connection,sql, new BeanHandler(Admin.class), 4); System.out.println(admin); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }