BeanCopier

cglib是一款比較底層的操做java字節碼的框架。 

下面經過拷貝bean對象來測試BeanCopier的特性: 

java

Java代碼   收藏代碼
  1. public class OrderEntity {  
  2.     private int id;  
  3.     private String name;  
  4.     // Getters and setters are omitted  
  5. }  

 

Java代碼   收藏代碼
  1. public class OrderDto {  
  2.     private int id;  
  3.     private String name;  
  4.     // Getters and setters are omitted  
  5. }  

 

Java代碼   收藏代碼
  1. public class PropWithDiffType {  
  2.     private Integer id;  
  3.     private String name;  
  4.     // Getters and setters are omitted  
  5. }  

 

Java代碼   收藏代碼
  1. public class LackOfSetter {  
  2.     private int id;  
  3.     private String name;  
  4.   
  5.     public LackOfSetter() {  
  6.     }  
  7.   
  8.     public LackOfSetter(int id, String name) {  
  9.         this.id = id;  
  10.         this.name = name;  
  11.     }  
  12.     // Getters and setters are omitted  
  13.     // public void setName(String name) {  
  14.     //  this.name = name;  
  15.     // }  
  16. }  



1. 屬性名稱、類型都相同: 框架

Java代碼   收藏代碼
  1. @Test  
  2. public void normalCopyTest() {  
  3.     OrderEntity entity = new OrderEntity();  
  4.     entity.setId(1);  
  5.     entity.setName("orderName");  
  6.     final BeanCopier copier = BeanCopier.create(OrderEntity.class, OrderDto.class, false);  
  7.     OrderDto dto = new OrderDto();  
  8.     copier.copy(entity, dto, null);  
  9.     Assert.assertEquals(1, dto.getId());  
  10.     Assert.assertEquals("orderName", dto.getName());  
  11. }  


結論:拷貝OK。 

2. 屬性名稱相同、類型不一樣: 

測試

Java代碼   收藏代碼
  1. @Test  
  2. public void sameNameDifferentTypeCopyTest() {  
  3.     OrderEntity entity = new OrderEntity();  
  4.     entity.setId(1);  
  5.     entity.setName("orderName");  
  6.     final BeanCopier copier = BeanCopier.create(OrderEntity.class, PropWithDiffType.class, false);  
  7.     PropWithDiffType dto = new PropWithDiffType();  
  8.     copier.copy(entity, dto, null);  
  9.     Assert.assertEquals(null, dto.getId()); // OrderEntity的id爲int類型,而PropWithDiffType的id爲Integer類型,不拷貝  
  10.     Assert.assertEquals("orderName", dto.getName());  
  11. }  


結論:名稱相同而類型不一樣的屬性不會被拷貝。 

注意:即便源類型是原始類型(int, short和char等),目標類型是其包裝類型(Integer, Short和Character等),或反之:都不會被拷貝。 

3. 源類和目標類有相同的屬性(二者的getter都存在),但目標類的setter不存在 this

Java代碼   收藏代碼
  1. @Test  
  2. public void targetLackOfSetterCopyTest() {  
  3.     OrderEntity entity = new OrderEntity();  
  4.     entity.setId(1);  
  5.     entity.setName("orderName");  
  6.     final BeanCopier copier = BeanCopier.create(OrderEntity.class, LackOfSetter.class, false);  // 拋NullPointerException  
  7.     LackOfSetter dto = new LackOfSetter();  
  8.     copier.copy(entity, dto, null);  
  9. }  


結論:建立BeanCopier的時候拋異常。 

致使異常的緣由是BeanCopier類的第128~133行 spa

Java代碼   收藏代碼
  1. for (int i = 0; i < setters.length; i++) { // 遍歷目標類的屬性描述集  
  2.     PropertyDescriptor setter = setters[i];  
  3.     PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName()); // 從源類獲取和目標類屬性名稱相同的屬性描述  
  4.     if (getter != null) {  
  5.         MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod()); // 獲取源類屬性的getter方法  
  6.         MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod()); // 獲取目標類屬性的setter方法。LackOfSetter類name屬性的setter方法沒有,因此報錯  



4. 源類或目標類的setter比getter少 orm

Java代碼   收藏代碼
  1. @Test  
  2. public void sourceLackOfSetterCopyTest() {  
  3.     LackOfSetter source = new LackOfSetter(1, "throne");  
  4.     final BeanCopier copier = BeanCopier.create(LackOfSetter.class, OrderDto.class, false);  
  5.     OrderDto dto = new OrderDto();  
  6.     copier.copy(source, dto, null);  
  7.     Assert.assertEquals(1, dto.getId());  
  8.     Assert.assertEquals("throne", dto.getName());  
  9. }  


結論:拷貝OK。此時的setter多餘,但不會報錯。 

總結: 

1. BeanCopier只拷貝名稱和類型都相同的屬性。 

2. 當目標類的setter數目比getter少時,建立BeanCopier會失敗而致使拷貝不成功。對象

相關文章
相關標籤/搜索