1. BeanCopier
默认只复制名称和类型相同的字段,对date为空的情况不进行复制。把相同的进行复制,把不同的,也就是需要我们个性化的一些字段,单独出来用set来赋值,这样程序就会很明确,重点也就聚焦在了不同的地方。
BeanCopier支持两种方式:
一种是不使用Converte
r的方式,仅对两个bean间属性名和类型完全相同的变量进行拷贝;
另一种则引入Converter
,可以对某些特定属性值进行特殊操作。
import org.springframework.cglib.beans.BeanCopier;
//1、source源;2、target目标;把源中的属性复制到目标中
BeanCopier.create(Source.class, Target.class, false)
.copy(source, target, null);
注:即使源类型是原始类型(int, short和char等),目标类型是其包装类型(Integer, Short和Character等),或反之,都不会被拷贝。
源码:
public static BeanCopier create(Class source, Class target, boolean useConverter) {
BeanCopier.Generator gen = new BeanCopier.Generator();
gen.setSource(source);
gen.setTarget(target);
gen.setUseConverter(useConverter);
return gen.create();
}
自定义转换器Converter
已知,当源和目标类的属性类型不同时,不能拷贝该属性,此时我们可以通过实现Converter接口来自定义转换器
public class UserConverter implements Converter{}
- 一旦使用Converter,BeanCopier只使用Converter定义的规则去拷贝属性,所以在convert()方法中要考虑所有的属性。
- 使用Converter会使对象拷贝速度变慢。
BeanCopier总结
- 当源类和目标类的属性名称、类型都相同,拷贝没问题。
- 当源对象和目标对象的属性名称相同、类型不同,那么名称相同而类型不同的属性不会被拷贝。注意,原始类型(int,short,char)和 他们的包装类型,在这里都被当成了不同类型,因此不会被拷贝。
- 源类或目标类的setter比getter少,拷贝没问题,此时setter多余,但是不会报错。
- 源类和目标类有相同的属性(两者的getter都存在),但是目标类的setter不存在,此时会抛出NullPointerException。
2. BeanUtils
Apache和Spring均有BeanUtils工具类, Apache的BeanUtils稳定性与效率都不行;Spring的BeanUtils比较稳定,不会因为量大了,耗时明显增加,故一般都使用Spring的BeanUtils。
import org.springframework.beans.BeanUtils
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, (Class)null, (String[])null);
}
Spring中的BeanUtils,其中实现的方式很简单,就是对两个对象中相同名字的属性进行简单get/set,仅检查属性的可访问性。成员变量赋值是基于目标对象的成员列表,并且会跳过ignore的以及在源对象中不存在的,所以这个方法是安全的,不会因为两个对象之间的结构差异导致错误,但是必须保证同名的两个成员变量类型相同。
BeanCopier拷贝速度比BeanUtils快,性能瓶颈出现在创建BeanCopier实例(create)的过程中。
所以,把创建过的BeanCopier实例放到缓存中,下次可以直接获取,提升性能