在日常开发中,我们经常需要给对象进行赋值,通常会调用其set/get 方法,有些时候,如果我们要转换的两个对象之间属性大致相同,会考虑使用属性拷贝工具进行。
如我们经常在代码中会对一个数据结构封装成DO、SDO、DTO、VO 等,而这些Bean中的大部分属性都是一样的,所以使用属性拷贝类工具可以帮助我们节省大量的set和get操作。
市面上有很多类似的工具类,在开发中比较常用的有Spring BeanUtils和Apache BeanUtils。那么,我们到底应该选择哪种工具类更加合适呢?下面通过代码来比较下。
首先定义一个User类:
public class User {
private String name;
private String phone;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
再定义一个UserDTO 类:
public class UserDTO {
private String name;
private String phone;
private Integer age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
使用Spring BeanUtils进行属性拷贝:
private void mappingBySpringBeanUtils(UserDTO userDTO, int times) {
StopWatch stopwatch = new StopWatch();
stopwatch.start();
for (int i = 0; i < times; i++) {
User user = new User();
org.springframework.beans.BeanUtils.copyProperties(userDTO, user);
}
stopwatch.stop();
System.out.println("mappingBySpringBeanUtils cost :" + stopwatch.getTotalTimeMillis());
}
使用Apache BeanUtils进行属性拷贝:
private void mappingByApacheBeanUtils(UserDTO userDTO, int times)
throws InvocationTargetException, IllegalAccessException {
StopWatch stopwatch = new StopWatch();
stopwatch.start();
for (int i = 0; i < times; i++) {
User user = new User();
org.apache.commons.beanutils.BeanUtils.copyProperties(userDTO, user);
}
stopwatch.stop();
System.out.println("mappingByApacheBeanUtils cost :" + stopwatch.getTotalTimeMillis());
}
然后执行以下代码:
UserDTO userDTO = new UserDTO();
userDTO.setName("张三");
userDTO.setPhone("13566668888");
userDTO.setAge(18);
userDTO.setAddress("浙江省杭州市");
mappingBySpringBeanUtils(userDTO, 1000);
mappingByApacheBeanUtils(userDTO, 1000);
mappingBySpringBeanUtils(userDTO, 10000);
mappingByApacheBeanUtils(userDTO, 10000);
结果如下:
从上面可以看出,在性能方面,Apache BeanUtils和Spring BeanUtils差距有点大。所以,如果考虑性能情况的话,建议不要选择Apache PropertyUtils而应该使用Spring BeanUtils。很多人会不理解,为什么大名鼎鼎的Apache 开源出来的的类库性能确不高呢?这不像是Apache 的风格呀,这背后导致性能低下的原因又是什么呢?其实,是因为Apache BeanUtils 力求做得完美, 在代码中增加了非常多的校验、兼容、日志打印等代码,过度的包装导致性能下降严重。