Spring中的BeanUtils與apache commons中的BeanUtils用法[1]


1. 前言

在開發過程中,經常遇到把要給一個bean的屬性賦給另外一個bean。最笨的方法是每個屬性都單獨寫一個,聰明的方法是應用反射寫一個工具方法。考慮到這個需求基本每個程序員都會遇到,那么一定已經有人完成了類似的代碼。搜一下,發現了Spring和apache commons都提供了這個方法,並且二者之間有點不同。在這里記錄一下這個兩個類的基本用法以及二者的區別。不過,除了這兩個類,應該還有很多類似的類都提供了此功能。

BeanUtils默認有好多方法,這篇主要描述copyProperties這個方法。

2. bean的定義

首先定義兩個bean。

public class BeanA {
    private String name1;
    private String name2;
    private List<String> nameList;
   
    public String getName1() {
        return name1;
    }
    public void setName1(String name1) {
        this.name1 = name1;
    }
    public String getName2() {
        return name2;
    }
    public void setName2(String name2) {
        this.name2 = name2;
    }
    public List<String> getNameList() {
        return nameList;
    }
    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }
}

public class BeanB {
    private String name1;
    private String name2;
    private List<String> nameList;
    public String getName1() {
        return name1;
    }
    public void setName1(String name1) {
        this.name1 = name1;
    }
    public String getName2() {
        return name2;
    }
    public void setName2(String name2) {
        this.name2 = name2;
    }
    public List<String> getNameList() {
        return nameList;
    }
    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }
}

3. 基本的賦值

兩個工具類都提供了copyProperties的方法,滿足對象復制的需求,其用法如下所示。

    public static void springTest1() {
        BeanA ba = new BeanA();
        BeanB bb = new BeanB();
        ba.setName1("ba-name1");
        ba.setName2("ba-name2");
        org.springframework.beans.BeanUtils.copyProperties(ba, bb);
        System.out.println(bb.getName1());
        System.out.println(bb.getName2());
    }

    public static void apacheTest1() {
        BeanA ba = new BeanA();
        BeanB bb = new BeanB();
        ba.setName1("ba-name1");
        ba.setName2("ba-name2");
        try {
            org.apache.commons.beanutils.BeanUtils.copyProperties(bb, ba);
        } catch (Throwable t) {
        }
        System.out.println(bb.getName1());
        System.out.println(bb.getName2());
    }

需要注意的地方是,二者調用參數的順序是相反的。

4. 只部分賦值

在對象間相互復制的時候,經常有只給部分字段賦值的需求。spring和apache commons用兩種方式實現了這個需求。
spring的方式是可以設置ignore的property,可以有多個property;apache commons的做法是可以給某一個屬性賦值。

    public static void springTest2() {
        BeanA ba = new BeanA();
        BeanB bb = new BeanB();
        ba.setName1("ba-name1");
        ba.setName2("ba-name2");
        bb.setName1("bb-name1");
        org.springframework.beans.BeanUtils.copyProperties(ba, bb, "name1");
        System.out.println(bb.getName1());
        System.out.println(bb.getName2());
    }

    public static void apacheTest2() {
        BeanA ba = new BeanA();
        BeanB bb = new BeanB();
        ba.setName1("ba-name1");
        ba.setName2("ba-name2");
        bb.setName1("bb-name1");
        bb.setName2("bb-name2");
        try {
            org.apache.commons.beanutils.BeanUtils.copyProperty(bb, "name1", ba);
        } catch (Throwable t) {
        }
        System.out.println(bb.getName1());
        System.out.println(bb.getName2());
    }

5. 關於引用類型

對於引用類型,二者都是修改引用地址。也就是說,如果修改了源對象里面的引用,則目標對象也會相應進行修改。

    public static void springTest3() {
        BeanA ba = new BeanA();
        BeanB bb = new BeanB();
        List<String> list = new ArrayList<String>();
        list.add("list-a-1");
        ba.setNameList(list);
        org.springframework.beans.BeanUtils.copyProperties(ba, bb);
        list.add("list-a-2");
        System.out.println(bb.getNameList().size());
    }

    public static void apacheTest3() {
        BeanA ba = new BeanA();
        BeanB bb = new BeanB();
        List<String> list = new ArrayList<String>();
        list.add("list-a-1");
        ba.setNameList(list);
        try {
            org.apache.commons.beanutils.BeanUtils.copyProperties(bb, ba);
        } catch (Throwable t) {
        }
        list.add("list-a-2");
        System.out.println(bb.getNameList().size());
    }

輸出

2
2

6.需要注意的地方

使用BeanUtils的成本驚人地昂貴。人做了一個簡單的測試,BeanUtils所花費的時間要超過取數 據、將其復制到對應的 value對象(通過手動調用get和set方法),以及通過串行化將其返回到遠程的客戶機的時間總和。

[這條我沒有測試過]

7.參考

Spring 中的BeanUtils與apache中的BeanUtils用法與比較
spring的BeanUtils.copyProperties用法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM