Bean拷贝工具类性能比较

引言

几年前做过一个项目,接入新的api接口。为了和api实现解耦,决定将api返回的实体类在本地也建一个。这样做有两个好处

  1. 可以在api变更字段的时候保持应用稳定性
  2. 可以对返回的实体的属性做处理,以提高可读性。例如接口返回long类型的时间戳,则将该字段在本地实体类中对应字段设置为date类型方便使用。

大致是这样的一个应用场景。当时刚毕业,充斥的都是A.setName(B.getName)这种类型的代码。当字段非常多的时候看起来非常臃肿,最重要的给人感觉不优雅。

再给我一次机会

如果上天再给我一次机会,我会跟他说,我有四种工具类可以优雅的解决这个问题。

分别是

  • org.apache.commons.beanutils.PropertyUtils.copyProperties
  • org.apache.commons.beanutils.BeanUtils.copyProperties
  • org.springframework.beans.BeanUtils.copyProperties
  • net.sf.cglib.beans.BeanCopier

Talk is cheap, show me code

定义SourceBean

package com.zhaoyangwoo.model;

/**
* Created by john on 16/7/28.
*/ public class SourceBean { private Integer age; private String title; private String source; private Boolean eat; public SourceBean(Integer i, String name, Boolean eat, String source) {
this.age = i;
this.title = name;
this.eat = eat;
this.source = source;
} public void setAge(Integer age) {
this.age = age;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public Boolean getEat() {
return eat;
} public void setEat(Boolean eat) {
this.eat = eat;
} public String getSource() {
return source;
} public void setSource(String source) {
this.source = source;
} public Integer getAge() {
return age;
} }

定义DesBean

package com.zhaoyangwoo.model;

/**
* Created by john on 16/7/28.
*/ public class DstBean { private Integer age; private String title; private Boolean eat; private String self; public String getSelf() {
return self;
} public void setSelf(String self) {
this.self = self;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public Boolean getEat() {
return eat;
} public void setEat(Boolean eat) {
this.eat = eat;
}
}

测试函数

package com.zhaoyangwoo.biz;

import com.zhaoyangwoo.model.DstBean;
import com.zhaoyangwoo.model.SourceBean;
import net.sf.cglib.beans.BeanCopier; /**
* Created by john on 16/7/28.
*/
public class BeanCopyMain { private static BeanCopier beanCopier = BeanCopier.create(SourceBean.class, DstBean.class, false); public static void main(String[] args) throws Exception { Integer[] times = {10000, 1000, 10}; for (int i = 0; i < times.length; i++) { Integer time = times[i];
doCopy(time, (x, y) -> org.apache.commons.beanutils.PropertyUtils.copyProperties(y, x), "org.apache.commons.beanutils.PropertyUtils.copyProperties");
doCopy(time, (x, y) -> org.apache.commons.beanutils.BeanUtils.copyProperties(y, x), "org.apache.commons.beanutils.BeanUtils.copyProperties");
doCopy(time, (x, y) -> org.springframework.beans.BeanUtils.copyProperties(y, x), "org.springframework.beans.BeanUtils.copyProperties");
doCopy(time, (x, y) -> beanCopier.copy(x, y, null), "net.sf.cglib.beans.BeanCopier.copy");
doCopy(time, (x, y) -> {
y.setEat(x.getEat());
y.setTitle(x.getTitle());
y.setAge(x.getAge());
}, "getter/setter");
}
} static void doCopy(Integer time, BeanCopy beanCopy, String type) throws Exception {
long startTime = System.currentTimeMillis();
for (int j = 0; j < time; j++) {
SourceBean sourceBean = new SourceBean(j, "source" + j, false, "abc");
DstBean dstBean = new DstBean();
beanCopy.copy(sourceBean, dstBean);
}
System.out.printf("执行%d次用时%dms---------%s%n", time, System.currentTimeMillis() - startTime, type);
} interface BeanCopy {
void copy(SourceBean from, DstBean to) throws Exception;
}
}

执行结果如下

结论

根据上面的运行结果,我们可以得出以下结论

  • property少,写起来也不麻烦,就直接用传统的getter/setter,性能最好
  • property多,转换不频繁,那就省点事吧,使用org.apache.commons.beanutils.BeanUtils.copyProperties
  • property多,转换很频繁,为性能考虑,使用net.sf.cglib.beans.BeanCopier.BeanCopier,性能近乎getter/setter。但是BeanCopier的创建时消耗较大,所以不要频繁创建该实体,最好的处理方式是静态化或者缓存起来。

[性能] Bean拷贝工具类性能比较的更多相关文章

  1. 就因为加了Lombok的@Accessors(chain = true),bean拷贝工具类不干活了

    前言 这次新建了一个工程,因为 Lombok 用得很习惯,但以前的话,一般只用了@Data,@AllArgsConstructor,@EqualsAndHashCode等常规注解:那这个Accesso ...

  2. 对象属性拷贝工具类大全==>Bean的属性拷贝从此不用愁

    大家在做java开发时,肯定会遇到api层参数对象传递给服务层,或者把service层的对象传递给dao层,他们之间又不是同一个类型对象,但字段又是一样,如果还是用普通的get.set方式来处理话,比 ...

  3. 可以随时拿取spring容器中Bean的工具类

    前言 在Spring帮我们管理bean后,编写一些工具类的时候需要从容器中拿到一些对象来做一些操作,比如字典缓存工具类,在没有找到字典缓存时,需要dao对象从数据库load一次,再次存入缓存中.此时需 ...

  4. Bean拷贝工具

    Apache BeanUtils Spring BeanUtils cglib BeanCopier Hutool BeanUtil Mapstruct Dozer 1.Apache  BeanUti ...

  5. java 常用Bean 转换工具类

    package com.hnf.framework.utils; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.data ...

  6. 获取Spring容器Bean对象工具类

    在开发中,总是能碰到用注解注入不了Spring容器里面bean对象的问题.为了解决这个问题,我们需要一个工具类来直接获取Spring容器中的bean.因此就写了这个工具类,在此记录一下,方便后续查阅. ...

  7. JavaBean递归拷贝工具类Dozer

    JavaBean深度拷贝利器——Dozer DozerBeanMapper对象之间相同属性名赋值 DozerBeanMapper + 对象转Map方法 Dozer(JavaBean的映射工具)开发手册

  8. spring 提供的属性值拷贝工具类

    当需要把一个原生的类中属性拷贝到扩展类中时,使用以下类很方便:

  9. Java Bean拷贝工具Orika原理解析

    最近面试被问及对象拷贝怎样才能高效,实际上问的就是Orika或者BeanCopier的原理.由于网上对Orika原理的解析并不太多-因此本文重点讲解一下Orika的原理.(Orika是基于JavaBe ...

随机推荐

  1. WinStore之Application Data

    一.Application Data简介 Applicaion Data相当于桌面应用的注册表,存储一些用户配置信息,如运行时状态,用户喜好等,需要注意的时,当卸载应用时,这些数据会被删除,所以不要存 ...

  2. 国行手机安装GOOGLE PLAY

    原文地址:http://blog.sina.com.cn/s/blog_68cff87b0101a96k.html 相信国行的手机都是没有google Play 功能的吧,相比其它国外的手机,功能上逊 ...

  3. Java Collection好文章

    Java Collection好文章 http://my.oschina.net/xiaomaoandhong/blog/78394

  4. HttpRequest重写,解决资源战胜/链接超时/分块下载事件通知 问题。

    /************************************************************************************** 文 件 名: WebRe ...

  5. ios开发人员mac空间不够用的解决办法

    有时候,当我们的mac硬盘空间不够用的时候,我们查看“用户”文件夹,发现这个文件夹占用了很大的存储空间,可是当我们一个一个查看这个文件夹下的子文件夹所占的存储空间大小并把这些存储空间大小加起来的时候却 ...

  6. osgi:设置httpservice端口号

    使用osgi开发http类的Service,在启动时默认端口是80.但有可能这个端口已经被本机上的其他程序占用.那么解决问题的方法有两种:1)关闭或修改占用程序的端口: 2)修改osgi启动时的端口. ...

  7. IOS中多版本,多设备类型支持注意事项

    IOS系统从07年出来,到现在也有6年了,每年发布一次到两次新的设备,从iPhone1,iPhone2 ... iPhone4s再到最新的iPhone5.硬件在升级的过程中CPU的架构也可能发生变化, ...

  8. android手势创建及识别

    使用一些浏览器或者输入法应用时会有一些手势操作,还可以自定义手势.这些神奇的操作是怎么做的呢?这一篇重点记录手势的识别和创建.这篇的内容使用到的是android.gesture包,具体的例子参考的是S ...

  9. SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework

    3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...

  10. 修改efi分区

    换了ssd硬盘,速度真快! 我特意准备了一个efi分区(fat32,忘记指定efi了),然而win10安装时不能指定启动位置,自己创建了一块. 下面我们把让win10使用自己创建的efi分区. 以管理 ...