關於Spring的BeanUtils


文章《用Spring的BeanUtils前,建議你先了解這幾個坑》里面,作者最后得到了這幾個結論:

1.Spring得BeanUtils得CopyProperties方法需要對應得屬性有getter和setter方法;
2.如果存在屬性完全相同得內部類,但是不是同一個內部類,即分別屬於各自得內部類,則Spring會認為屬性不同,不會Copy;
3.泛型只在編譯期起作用,不能依靠泛型來做運行期得限制;
4.最后,Spring和Apache得copy屬性得方法源和目的參數得位置正好相反,所以導包和調用得時候需要注意以下。
在這里,我們今天重點說的是第二點,第一點是因為用反射拿到set和get方法再去拿屬性值和設置屬性值的,不懂反射的人可以自行百度下。第三和第四點很簡單了應該是不需要解釋的。

驗證

首先,我把我自己的測試代碼也貼出來:

@Data
public class TestEntity{
private Integer age;
private String name;
private Inner inner;

@Data
public static class Inner{
    private Integer a;
    public Inner(Integer a){
        this.a = a;
    }
}

}

@Data
public class TestVO{
private Integer age;
private String name;
private Inner inner;

@Data
public static class Inner{
    private Integer a;
    public Inner(Integer a){
        this.a = a;
    }
}

}

public class Main{
public static void main(String args[]){
TestEntity entity = new TestEntity();
entity.setAge(1);
entity.setName("hehe");
entity.setInner(new TestEntity.Inner(1));

    TestVO vo = new TestVO();
    BeanUtils.copyProperties(entity,vo);
    System.out.println(vo.toString());
    
}

}
以上就是我得三個類,是不是超級簡單,比如工作中將entity轉vo,就有這種使用場景,運行main方法,測試結果和那個作者得出的第二點的結論是一樣的,b對象里面的inner是null!

file
但是這個是為什么呢?這個是BUG嗎?這個也是我今天要說的重點。

內部類

我們知道,java給我們提供了內部類這樣的東東,但是java的內部類,它其實只是java的一個語法糖而已(不知道什么是語法糖的請自行百度),那么我們定義得兩個JAVA類里面的Inner的真面目到底是怎樣的呢?

來到編譯后的.class文件目錄下,我們可以看到編譯后得.class文件:

file
哈哈,不知道讀者到這里是不是能明白些什么了呢?為什么經過BeanUtils.CopyProperties(entity,vo)之后,vo里面的inner還是null,因為TestEntity.java和TestVO.java里面的Inner在編譯之后的class名字都不一樣(代表加載到虛擬機之后的地址不同),怎么可能拷貝成功呢?

那么問題來了哈,我們怎樣用才能讓其拷貝成功呢?我稍微修改了下我的代碼如下:

@Data
public class TestVO{
private Integer age;
private String name;
private TestEntity.Inner inner;

}
僅僅是把Inner變為了TestEntity.Inner,刪掉了沒引用得內部類Inner,Main.java不變,然后運行結果如下:

file
可以看到,b對象里面的inner被成功拷貝過來。

此時編譯后得class文件也由5個變為了4個
file


免責聲明!

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



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