[性能] Bean拷贝工具类性能比较
Bean拷贝工具类性能比较
引言
几年前做过一个项目,接入新的api接口。为了和api实现解耦,决定将api返回的实体类在本地也建一个。这样做有两个好处
- 可以在api变更字段的时候保持应用稳定性
- 可以对返回的实体的属性做处理,以提高可读性。例如接口返回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拷贝工具类性能比较的更多相关文章
- 就因为加了Lombok的@Accessors(chain = true),bean拷贝工具类不干活了
前言 这次新建了一个工程,因为 Lombok 用得很习惯,但以前的话,一般只用了@Data,@AllArgsConstructor,@EqualsAndHashCode等常规注解:那这个Accesso ...
- 对象属性拷贝工具类大全==>Bean的属性拷贝从此不用愁
大家在做java开发时,肯定会遇到api层参数对象传递给服务层,或者把service层的对象传递给dao层,他们之间又不是同一个类型对象,但字段又是一样,如果还是用普通的get.set方式来处理话,比 ...
- 可以随时拿取spring容器中Bean的工具类
前言 在Spring帮我们管理bean后,编写一些工具类的时候需要从容器中拿到一些对象来做一些操作,比如字典缓存工具类,在没有找到字典缓存时,需要dao对象从数据库load一次,再次存入缓存中.此时需 ...
- Bean拷贝工具
Apache BeanUtils Spring BeanUtils cglib BeanCopier Hutool BeanUtil Mapstruct Dozer 1.Apache BeanUti ...
- java 常用Bean 转换工具类
package com.hnf.framework.utils; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.data ...
- 获取Spring容器Bean对象工具类
在开发中,总是能碰到用注解注入不了Spring容器里面bean对象的问题.为了解决这个问题,我们需要一个工具类来直接获取Spring容器中的bean.因此就写了这个工具类,在此记录一下,方便后续查阅. ...
- JavaBean递归拷贝工具类Dozer
JavaBean深度拷贝利器——Dozer DozerBeanMapper对象之间相同属性名赋值 DozerBeanMapper + 对象转Map方法 Dozer(JavaBean的映射工具)开发手册
- spring 提供的属性值拷贝工具类
当需要把一个原生的类中属性拷贝到扩展类中时,使用以下类很方便:
- Java Bean拷贝工具Orika原理解析
最近面试被问及对象拷贝怎样才能高效,实际上问的就是Orika或者BeanCopier的原理.由于网上对Orika原理的解析并不太多-因此本文重点讲解一下Orika的原理.(Orika是基于JavaBe ...
随机推荐
- 在linux下安装Xwindows
检查Linux系统是否能够联网. 执行命令 yum -y groupinstall Desktop 等上面的命令执行完后,再执行这条命令 yum -y groupinstall "X Win ...
- windows 程序设计自学:添加图标资源
#include <windows.h> #include "resource.h" LRESULT CALLBACK MyWndProc( HWND hwnd, // ...
- SSAS:概念梳理
Dimension Objects 原文 A simple Dimension object is composed of basic information, attributes, and hie ...
- 64bit ubuntu 安装32bit的软件
在64bit的系统上安装32bit的软件时,会提示: file not found or no such file. 此时只需要安装 sudo apt-get install libc6-dev-i3 ...
- 构造Lambda表达式
/// <summary> /// 构造Lambda表达式 /// </summary> /// <typeparam name="T">< ...
- JS基础回顾,小练习(判断数组,以及函数)
追梦子博客版权所有. // 判断arr是否为一个数组,返回一个bool值 方法1: function isArray(arr) { var str = arr.__proto__.constructo ...
- Knockout 新版应用开发教程之"text"绑定
目的 DOM元素显示文本的值是你传递的参数,前提是text先绑定到该元素上 典型的常用元素 <span>或者<em>习惯性的用来显示文本,但是在技术上来说你可以用任何元素的. ...
- Robot Framework自动化测试(一)---第一个脚本
最近工具中用Robot Framework框架来做自动化,所以,花时间学习了一下. =======所需环境=================== Python: https://www.python. ...
- SQL Server中的事务日志管理(5/9):完整恢复模式里的日志管理
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- 探秘空值位图掩码(NULL bitmap mask)
这篇文章我想谈下空值位图掩码(NULL bitmap mask) ,并揭开它的神秘面纱.空值位图掩码是在存储引擎层为列是否存储NULL值进行编码.它是一个简单的位图掩码,如果值是1的话,表示这列有NU ...