cglib BeanCopier 使用

cglib BeanCopier 使用cglib是一款比较底层的操作java字节码的框架。 下面通过拷贝bean对象来测试BeanCopier的特性: Java代码  public class OrderEntity {      private int id;      private String name;      // Getters and setters are o

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

cglib是一款比较底层的操作java字节码的框架。 

下面通过拷贝bean对象来测试BeanCopier的特性: 

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.classfalse);  
  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.classfalse);  
  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不存在
 

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.classfalse);  // 抛NullPointerException  
  7.     LackOfSetter dto = new LackOfSetter();  
  8.     copier.copy(entity, dto, null);  
  9. }  



结论:创建BeanCopier的时候抛异常。 




导致异常的原因是BeanCopier类的第128~133行 

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少
 

Java代码  
收藏代码

  1. @Test  
  2. public void sourceLackOfSetterCopyTest() {  
  3.     LackOfSetter source = new LackOfSetter(1“throne”);  
  4.     final BeanCopier copier = BeanCopier.create(LackOfSetter.class, OrderDto.classfalse);  
  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会失败而导致拷贝不成功。



——————————–2222222222222222222222222222222————————————————————–

当源和目标类的属性类型不同时,不能拷贝该属性,此时我们可以通过实现Converter接口来自定义转换器: 



源类和目标类: 

Java代码  
收藏代码

  1. public class AccountEntity {  
  2.     private int id;  
  3.     private Timestamp createTime;  
  4.     private BigDecimal balance;  
  5.     // Getters and setters are omitted  
  6. }  


Java代码  
收藏代码

  1. public class AccountDto {  
  2.     private int id;  
  3.     private String name;  
  4.     private String createTime;  
  5.     private String balance;  
  6.     // Getters and setters are omitted  
  7. }  





1. 不使用Converter
 



Java代码  
收藏代码

  1. public class BeanCopierConverterTest {  
  2.   
  3.     @Test  
  4.     public void noConverterTest() {  
  5.         AccountEntity po = new AccountEntity();  
  6.         po.setId(1);  
  7.         po.setCreateTime(new Timestamp(10043143243L));  
  8.         po.setBalance(BigDecimal.valueOf(4000L));  
  9.         BeanCopier copier = BeanCopier.create(AccountEntity.class, AccountDto.classfalse);  
  10.         AccountDto dto = new AccountDto();  
  11.         copier.copy(po, dto, null);  
  12.         Assert.assertNull(dto.getCreateTime()); // 类型不同,未拷贝  
  13.         Assert.assertNull(dto.getBalance()); // 类型不同,未拷贝  
  14.     }  
  15. }  





2. 使用Converter
 




基于目标对象的属性出发,如果源对象有相同名称的属性,则调一次convert方法: 



Java代码  
收藏代码

  1. package net.sf.cglib.core;  
  2.   
  3. public interface Converter {  
  4.     // value 源对象属性,target 目标对象属性类,context 目标对象setter方法名  
  5.     Object convert(Object value, Class target, Object context);  
  6. }  




Java代码  
收藏代码

  1. @Test  
  2. public void converterTest() {  
  3.     AccountEntity po = new AccountEntity();  
  4.     po.setId(1);  
  5.     po.setCreateTime(Timestamp.valueOf(“2014-04-12 16:16:15”));  
  6.     po.setBalance(BigDecimal.valueOf(4000L));  
  7.     BeanCopier copier = BeanCopier.create(AccountEntity.class, AccountDto.classtrue);  
  8.     AccountConverter converter = new AccountConverter();  
  9.     AccountDto dto = new AccountDto();  
  10.     copier.copy(po, dto, converter);  
  11.     Assert.assertEquals(“2014-04-12 16:16:15”, dto.getCreateTime());  
  12.     Assert.assertEquals(“4000”, dto.getBalance());  
  13. }  
  14.   
  15. static class AccountConverter implements Converter {  
  16.   
  17.     SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);  
  18.   
  19.     @SuppressWarnings(“rawtypes”)  
  20.     @Override  
  21.     public Object convert(Object value, Class target, Object context) {  
  22.         if (value instanceof Integer) {  
  23.             return (Integer) value;  
  24.         } else if (value instanceof Timestamp) {  
  25.             Timestamp date = (Timestamp) value;  
  26.             return sdf.format(date);  
  27.         } else if (value instanceof BigDecimal) {  
  28.             BigDecimal bd = (BigDecimal) value;  
  29.             return bd.toPlainString();  
  30.         }  
  31.         return null;  
  32.     }  
  33. }  




注:一旦使用Converter,BeanCopier只使用Converter定义的规则去拷贝属性,所以在convert方法中要考虑所有的属性。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/197132.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • smote算法_探索SMOTE算法

    smote算法_探索SMOTE算法SMOTE是一种综合采样人工合成数据算法,用于解决数据类别不平衡问题(Imbalancedclassproblem),以Over-sampling少数类和Under-sampling多数类结合的方式来合成数据。本文将以NiteshV.Chawla(2002)的论文为蓝本,阐述SMOTE的核心思想以及实现其朴素算法,在传统分类器(贝叶斯和决策树)上进行对比算法性能并且讨论其算法改进的途径…

  • nginx开源_NGINX反向代理

    nginx开源_NGINX反向代理Nginx源码分析-初探Nginx的架构 Nginx源码分析-基础数据结构篇-内存池ngx_palloc.c Nginx源码分析-基础数据结构篇-数组结构ngx_array.c Nginx源码分析-基础数据结构篇-缓冲区结构ngx_buf.c Nginx源码分析-基础数据结构篇-双向链表结构ngx_queue.c Nginx源码分析……

  • 详解linux中rsync的妙用[通俗易懂]

    详解linux中rsync的妙用[通俗易懂]????1.rsync备份服务器软件介绍:Rsync是一款开源的、快速的、多功能的、可实现全量及增长的本地或远程数据同步备份的优秀工具。增量备份:只同步变化的数据细腻些,主要利用了quickcheck算法实现同步原理:1)建立好网络连接2)先进行数据信息对比3)只将变化的数据进行增量备份2.rsync软件作用说明:(1v4cp/scp/rm/ls)本地数据备份:cp[root@backup~]#cp-a/etc/hosts/tmp/hosts_cp[root@backu

    2022年10月13日
  • python语法:如何通过value找key[通俗易懂]

    python语法:如何通过value找key[通俗易懂]python语法:如何通过value找key

  • http错误状态码_HTTP常用的14种状态码

    http错误状态码_HTTP常用的14种状态码一些常见的状态码为:200-服务器成功返回网页404-请求的网页不存在503-服务不可用详细分解:1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码。代码说明100(继续)请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。101(切换协议)请求者已要求服务器切换协议,服务器已确认并准备切换。…

  • 清关报关知识详解_海关清关中是什么意思

    清关报关知识详解_海关清关中是什么意思  加工中心清关代理流程报关知识科普    进口泰国二手加工中心清关代理流程报关知识科普    机电企业产品的定义:机电技术产品是指使用进行机械、电器、电子信息设备所生产的各类农具机械、电器、电子系统性能的生产管理设备和生活用机具。一般包括机械设备、电气设备、运输工具、电子产品、电子产品、仪器仪表、金属产品及其零部件。    那么什么是二手设备?    (一)已经可以使用(不含使用前测试、调试的设备),仍具备基本信息功能和一定能够使用时间价值的;    (二)未经使用,但是超过质量保

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号