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

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

  1. public class OrderEntity {
  2. private int id;
  3. private String name;
  4. // Getters and setters are omitted
  5. }
  1. public class OrderDto {
  2. private int id;
  3. private String name;
  4. // Getters and setters are omitted
  5. }
  1. public class PropWithDiffType {
  2. private Integer id;
  3. private String name;
  4. // Getters and setters are omitted
  5. }
  1. public class LackOfSetter {
  2. private int id;
  3. private String name;
  4. public LackOfSetter() {
  5. }
  6. public LackOfSetter(int id, String name) {
  7. this.id = id;
  8. this.name = name;
  9. }
  10. // Getters and setters are omitted
  11. // public void setName(String name) {
  12. //  this.name = name;
  13. // }
  14. }

1. 属性名称、类型都相同:

  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. 属性名称相同、类型不同:

  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不存在

  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行

  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少

  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会失败而导致拷贝不成功。

BeanCopier的更多相关文章

  1. 使用 BeanCopier 复制对象

    Cglib是一款比较底层的操作java字节码的框架. BeanCopier是一个工具类,可以用于Bean对象内容的复制. 复制Bean对象内容的方法有很多,比如自己手动get set ,或者使用Pro ...

  2. 对象拷贝类PropertyUtils,BeanUtils,BeanCopier的技术沉淀

    功能简介 对象拷贝的应用现状简介: 业务系统中经常需要两个对象进行属性的拷贝,不能否认逐个的对象拷贝是最快速最安全的做法,但是当数据对象的属性字段数量超过程序员的容忍的程度,代码因此变得臃肿不堪,使用 ...

  3. 基于Emit实现的C#版本的BeanCopier

    在java的技术栈当中,著名的Cglib库里面有一个BeanCopier,这个类的功能就是可以完成两个对象的属性复制工作(哪怕属于两个不同的类). 今天本人通过.net内置的System.Reflec ...

  4. 使用CGlib实现Bean拷贝(BeanCopier)

    在做业务的时候,我们有时为了隔离变化,会将DAO查询出来的Entity,和对外提供的DTO隔离开来.大概90%的时候,它们的结构都是类似的,但是我们很不喜欢写很多冗长的b.setF1(a.getF1( ...

  5. BeanCopier使用说明

    BeanCopier从名字可以看出了,是一个快捷的bean类复制工具类. 一 如何使用,我就直接丢代码了 public class BeanCopierTest { static SimpleDate ...

  6. Bean复制的几种框架性能比较(Apache BeanUtils、PropertyUtils,Spring BeanUtils,Cglib BeanCopier)

    转自:http://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html 比较的是四种复制的方式,分别为Apache的BeanUtils和Prope ...

  7. BeanCopier类

    网上学习了一番BeanCopier类. cglib是一款比较底层的操作java字节码的框架. 下面通过拷贝bean对象来测试BeanCopier的特性: public class OrderEntit ...

  8. BeanCopier对象复制学习

    BeanCopier是Cglib包中的一个类,用于对象的复制. 注意:目标对象必须先实例化  而且对象必须要有setter方法 初始化例子:   BeanCopier copier = BeanCop ...

  9. BeanCopier的使用

    BeanCopier进行的是bean之间的copy,从一个类到另一个类,进行属性值的拷贝. 成功copy的条件: 1.属性的类型和名称都相同 2.目标类的setter缺少或缺失会导致拷贝失败,名称相同 ...

随机推荐

  1. 用 Python 带你看《我不是药神》

    我们都是小人物,我们都得了同一种病,我们都穷.——<我不是药神> 我不是程序员 我就是想求求你们,别动不动就拿篇10W+的文章来吓唬人好吗?说点有用的东西好吗?我们需要精神粮食不需要腐蚀精 ...

  2. mybatis学习(一)-------XML 映射配置文件详解

    XML 映射配置文件 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配 ...

  3. arduino八段数码管使用

    一:八段数码管的使用 控制要求:0-9的计时数据 实物连接图: 控制代码: //智慧自动化2018.6.11 ;//定义数字接口7 连接a 段数码管 ;// 定义数字接口6 连接b 段数码管 ;// ...

  4. Java+Netty实现的RESTful框架--netty-rest-server

    在工作中用Netty做了几个服务,感觉Netty做出来的程序性能好,资源占用少,但是实现Http服务比较麻烦,于是就参考Spring MVC的注解基于Netty实现了一个轻量级的RESTful框架. ...

  5. Django中settings设计模式(单例模式)

    配置文件: 需求:配置文件,默认配置和手动配置分开,参考django的配置文件方案,默认配置文件放在项目容器内部,只让用户做常用配置. /bin/settings.py(手动配置) PLUGIN_IT ...

  6. Java子类初始化调用父类无参构造

    实在是服了自己,子类初始化调用父类无参构造这种初学者都应该知道的事,我给忘了. 记得当初看书的时候各种概念抄在笔记本上,再上机实践,以为一辈子都不会忘,还是给忘了. 这件事说明了两个问题: 1.我没有 ...

  7. SICP读书笔记 2.1

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  8. 学习python,第三篇:.pyc是个什么鬼?

    .pyc是个什么鬼? 1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存 ...

  9. Netty源码分析第2章(NioEventLoop)---->第5节: 优化selector

    Netty源码分析第二章: NioEventLoop   第五节: 优化selector 在剖析selector轮询之前, 我们先讲解一下selector的创建过程 回顾之前的小节, 在创建NioEv ...

  10. Netty源码分析第3章(客户端接入流程)---->第3节: NioSocketChannel的创建

    Netty源码分析第三章: 客户端接入流程 第三节: NioSocketChannel的创建 回到上一小节的read()方法: public void read() { //必须是NioEventLo ...