BeanCopier

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

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

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行

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

时间: 2024-10-12 21:56:25

BeanCopier的相关文章

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

对象拷贝类PropertyUtils,BeanUtils,BeanCopier的技术沉淀 性能对比: BeanCopier > PropertyUtils > BeanUtils. 其中BeanCopier的性能高出另外两个100数量级. BeanCopier使用可参考: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp36 对象拷贝的应用现状简介: 业务系统中经常需要两个对象进行属性的拷贝,不能否认逐个的对象拷贝是最快速最

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

 文章转载来自:http://www.cnblogs.com/kaka/archive/2013/03/06/2945514.html 作为一个新员工,一个首要的工作就是阅读别人的代码,阅读代码的诸多好处就不说了,我就直奔主题,通过预读代码,发现了几种实现两个不同类型的Bean之 间实现值复制的几种方式,上网查询后发现性能上会有差异,于是就萌生自己深入了解几种实现的想法.第一步就是先本着实事求是的原则去探求一下大家总结出来 的性能差异是否正确. 比较的是四种复制的方式,分别为Apache的Bea

关于BeanCopier的一些思考

在做业务的时候,我们有时为了隔离变化,会将DAO查询出来的Entity,和对外提供的DTO隔离开来.大概90%的时候,它们的结构都是类似的,但是我们很不喜欢写很多冗长的b.setF1(a.getF1())这样的代码,于是我们需要BeanCopier来帮助我们. BeanCopier其实已经有很多开源版本,例如DozerMapper.Apache BeanUtils.Spring.Jodd BeanUtils甚至是Cglib都提供了这样的功能.在比较这些工具之前,我想先提提我对BeanCopier

使用 BeanCopier 复制对象

Cglib是一款比较底层的操作java字节码的框架. BeanCopier是一个工具类,可以用于Bean对象内容的复制. 复制Bean对象内容的方法有很多,比如自己手动get set ,或者使用PropertyUtils或者使用BeanUtils BeanCopier与 PropertyUtils .BeanUtils的不同在于: PropertyUtils 和 BeanUtils 使用的是反射机制来完成属性的复制. 而BeanCopier 的原理是通过字节码动态生成一个类,这个里面实现get

对比BeanUtils、PropertyUtils、BeanCopier的性能消耗

主要代码 定义2个bean对象: public class copyPropertiesData1 { private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } } public class copyPropertiesData2 { private Integer id; public Integer getId() { return id;

BeanCopier对象复制学习

BeanCopier是Cglib包中的一个类,用于对象的复制. 注意:目标对象必须先实例化  而且对象必须要有setter方法 初始化例子:   BeanCopier copier = BeanCopier.create(Source.class, Target.class, false); copier.copy(source, target, null); 第三个参数useConverter,是否开启Convert.默认BeanCopier只会做同名,同类型属性的copier,否则就会报错.

spring源码分析(一)IoC、DI

创建日期:2016.08.06 修改日期:2016.08.07 - 2016.08.12 交流QQ:992591601 参考书籍:<spring源码深度解析>.<spring技术内幕> 参考文章:http://www.cnblogs.com/xing901022/p/4178963.html http://www.myexception.cn/program/1031276.html http://blog.csdn.net/qian_348840260/article/detai

Spring-core中的cglib小用法

对象复制听说用这个更高效 /** * 拷贝对象 * @param src 源对象 * @param dist 需要赋值的对象 */ public static void copy(Object src, Object dist) { BeanCopier copier = BeanCopier .create(src.getClass(), dist.getClass(), false); copier.copy(src, dist, null); } /** * 拷贝对象 * @param s

cglib源码学习交流

背景 前段时间在工作中,包括一些代码阅读过程中,spring aop经常性的会看到cglib中的相关内容,包括BeanCopier,BulkBean,Enancher等内容,以前虽大致知道一些内容,原理是通过bytecode,但没具体深入代码研究,只知其所用不知其所以然,所以就特地花了半天多的工作时间研究了CGLIB的相关源码,同时结合看了下 spring Aop中对CGLIB的使用. cglib基本信息 cglib的官方网站: http://cglib.sourceforge.net/ cgl