BeanCopier系列之二:使用Converter
BeanCopier系列之三:缓存BeanCopier提升性能
cglib是一款比较底层的操作java字节码的框架。
下面通过拷贝bean对象来测试BeanCopier的特性:
public class OrderEntity {
private int id;
private String name;
// Getters and setters are omitted
}
public class OrderDto {
private int id;
private String name;
// Getters and setters are omitted
}
public class PropWithDiffType {
private Integer id;
private String name;
// Getters and setters are omitted
}
public class LackOfSetter {
private int id;
private String name;
public LackOfSetter() {
}
public LackOfSetter(int id, String name) {
this.id = id;
this.name = name;
}
// Getters and setters are omitted
// public void setName(String name) {
// this.name = name;
// }
}
1. 属性名称、类型都相同:
@Test
public void normalCopyTest() {
OrderEntity entity = new OrderEntity();
entity.setId(1);
entity.setName("orderName");
final BeanCopier copier = BeanCopier.create(OrderEntity.class, OrderDto.class, false);
OrderDto dto = new OrderDto();
copier.copy(entity, dto, null);
Assert.assertEquals(1, dto.getId());
Assert.assertEquals("orderName", dto.getName());
}
结论:拷贝OK。
2. 属性名称相同、类型不同:
@Test
public void sameNameDifferentTypeCopyTest() {
OrderEntity entity = new OrderEntity();
entity.setId(1);
entity.setName("orderName");
final BeanCopier copier = BeanCopier.create(OrderEntity.class, PropWithDiffType.class, false);
PropWithDiffType dto = new PropWithDiffType();
copier.copy(entity, dto, null);
Assert.assertEquals(null, dto.getId()); // OrderEntity的id为int类型,而PropWithDiffType的id为Integer类型,不拷贝
Assert.assertEquals("orderName", dto.getName());
}
结论:名称相同而类型不同的属性不会被拷贝。
注意:即使源类型是
原始类型(int, short和char等),目标类型是其
包装类型(Integer, Short和Character等),或反之:都
不会被拷贝。
3. 源类和目标类有相同的属性(两者的getter都存在),但目标类的setter不存在
@Test
public void targetLackOfSetterCopyTest() {
OrderEntity entity = new OrderEntity();
entity.setId(1);
entity.setName("orderName");
final BeanCopier copier = BeanCopier.create(OrderEntity.class, LackOfSetter.class, false); // 抛NullPointerException
LackOfSetter dto = new LackOfSetter();
copier.copy(entity, dto, null);
}
结论:创建BeanCopier的时候抛异常。
导致异常的原因是BeanCopier类的第128~133行
for (int i = 0; i < setters.length; i++) { // 遍历目标类的属性描述集
PropertyDescriptor setter = setters[i];
PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName()); // 从源类获取和目标类属性名称相同的属性描述
if (getter != null) {
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod()); // 获取源类属性的getter方法
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod()); // 获取目标类属性的setter方法。LackOfSetter类name属性的setter方法没有,所以报错
4. 源类或目标类的setter比getter少
@Test
public void sourceLackOfSetterCopyTest() {
LackOfSetter source = new LackOfSetter(1, "throne");
final BeanCopier copier = BeanCopier.create(LackOfSetter.class, OrderDto.class, false);
OrderDto dto = new OrderDto();
copier.copy(source, dto, null);
Assert.assertEquals(1, dto.getId());
Assert.assertEquals("throne", dto.getName());
}
结论:拷贝OK。此时的setter多余,但不会报错。
总结:
1. BeanCopier只拷贝名称和类型都相同的属性。
2. 当目标类的setter数目比getter少时,创建BeanCopier会失败而导致拷贝不成功。
分享到:
相关推荐
at net.sf.cglib.beans.BeanCopier$Generator.generateClass(BeanCopier.java:133) at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) at ...
对象复制工具,基于cglib BeanCopier 实现对实体对象、持久化对象、代理对象的克隆和复制, 避免重复克隆和复制,避免无限循环引用,(校验hashCode) 可指定实体对象和集合属性的克隆深度
首先,Apache BeanUtils是Apache Commons项目的一部分,提供了一系列便捷的工具方法用于Bean的操作,包括属性的复制。它使用反射机制实现,通过getter和setter方法进行属性的读写。其优点在于简单易用,但缺点是在...
bean copy。
这个库的目标是提供一种高效且便捷的方式,将一个对象的属性值复制到另一个对象上,无论这两个对象是否具有相同的结构。它通过反射技术自动映射源对象和目标对象的公共属性,极大地减少了手动编写复制代码的繁琐工作...
- **性能问题**:相较于其他工具如Spring BeanUtils或Cglib BeanCopier,Apache Beanutils在性能上表现不佳。 - **安全漏洞**:Apache Beanutils存在反射调用的安全隐患,可能导致远程代码执行等问题。 - **类型...
本来想自己用反射来做一个,因为cglib使用了动态字节码生成,所以效率比反射要高,参考了一些工具,决定直接在cglib的BeanCopier上改了特点本着为90%的使用场景,提供更便捷和直观的功能的思想,我又造了一个轮子。...
MapStruct是一种高效的对象映射框架,它通过注解处理器自动生成类型安全、高性能且无依赖的JavaBean映射代码。在Java开发中,JavaBean之间的转换通常是一个繁琐的任务,尤其是在大型项目中,大量的转换代码不仅影响...
在上述示例中,`BeanCopier`被用来快速地将`OrderState`的属性复制到`Order`对象,这是一种高效的对象复制方式。使用者可以通过调用`Order.builder()`开始构建过程,然后通过一系列的`build`方法设置属性,最后调用`...
相比之下,使用mapstruct来进行属性转换是一个更好的选择。mapstruct是一个基于注解的属性转换工具,可以自动地将一个对象的属性转换到另一个对象中。使用mapstruct可以避免类型转换异常和其他风险。例如: ```java...
Java开发手册是Java开发者必备的指南之一,本手册中提到了许多Java开发中的最佳实践和注意事项。下面我们就从给定的文件中总结出一些重要的知识点: 1.为什么禁止使用Apache Beanutils进行属性的copy? 在Java开发...
相比其他如Spring的BeanUtils、Cglib的BeanCopier等工具,BeanUtils在处理大量对象复制时可能会导致性能瓶颈。这是因为BeanUtils内部实现中涉及了反射和异常处理,这些操作在循环中大量执行时会消耗更多的时间。 ...