開發框架時,經常需要使用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的例子:
//javaBean
public 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.txt
com.rlovep.bean.Person
id=22
name=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<String, Object> 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<String, Object> 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<String, Object> 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>(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();
}
}
}
封裝javaBean的方法介紹就到這里.來自一條小鯊魚wpeace(rlovep.com)