Bean拷贝工具类性能比较

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 {

<span class="hljs-keyword">private</span> Integer age;

<span class="hljs-keyword">private</span> String title;

<span class="hljs-keyword">private</span> String source;

<span class="hljs-keyword">private</span> Boolean eat;

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">SourceBean</span><span class="hljs-params">(Integer i, String name, Boolean eat, String source)</span> </span>{
    <span class="hljs-keyword">this</span>.age = i;
    <span class="hljs-keyword">this</span>.title = name;
    <span class="hljs-keyword">this</span>.eat = eat;
    <span class="hljs-keyword">this</span>.source = source;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span><span class="hljs-params">(Integer age)</span> </span>{
    <span class="hljs-keyword">this</span>.age = age;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getTitle</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> title;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setTitle</span><span class="hljs-params">(String title)</span> </span>{
    <span class="hljs-keyword">this</span>.title = title;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> Boolean <span class="hljs-title">getEat</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> eat;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setEat</span><span class="hljs-params">(Boolean eat)</span> </span>{
    <span class="hljs-keyword">this</span>.eat = eat;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getSource</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> source;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setSource</span><span class="hljs-params">(String source)</span> </span>{
    <span class="hljs-keyword">this</span>.source = source;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> age;
}

}

定义DesBean

package com.zhaoyangwoo.model;

/**

  • Created by john on 16/7/28.
    */

public class DstBean {

<span class="hljs-keyword">private</span> Integer age;

<span class="hljs-keyword">private</span> String title;

<span class="hljs-keyword">private</span> Boolean eat;

<span class="hljs-keyword">private</span> String self;

<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getSelf</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> self;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setSelf</span><span class="hljs-params">(String self)</span> </span>{
    <span class="hljs-keyword">this</span>.self = self;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> age;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span><span class="hljs-params">(Integer age)</span> </span>{
    <span class="hljs-keyword">this</span>.age = age;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getTitle</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> title;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setTitle</span><span class="hljs-params">(String title)</span> </span>{
    <span class="hljs-keyword">this</span>.title = title;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> Boolean <span class="hljs-title">getEat</span><span class="hljs-params">()</span> </span>{
    <span class="hljs-keyword">return</span> eat;
}

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setEat</span><span class="hljs-params">(Boolean eat)</span> </span>{
    <span class="hljs-keyword">this</span>.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);

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{

    Integer[] times = {<span class="hljs-number">10000</span>, <span class="hljs-number">1000</span>, <span class="hljs-number">10</span>};

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; times.length; i++) {

        Integer time = times[i];
        doCopy(time, (x, y) -&gt; org.apache.commons.beanutils.PropertyUtils.copyProperties(y, x), <span class="hljs-string">"org.apache.commons.beanutils.PropertyUtils.copyProperties"</span>);
        doCopy(time, (x, y) -&gt; org.apache.commons.beanutils.BeanUtils.copyProperties(y, x), <span class="hljs-string">"org.apache.commons.beanutils.BeanUtils.copyProperties"</span>);
        doCopy(time, (x, y) -&gt; org.springframework.beans.BeanUtils.copyProperties(y, x), <span class="hljs-string">"org.springframework.beans.BeanUtils.copyProperties"</span>);
        doCopy(time, (x, y) -&gt; beanCopier.copy(x, y, <span class="hljs-keyword">null</span>), <span class="hljs-string">"net.sf.cglib.beans.BeanCopier.copy"</span>);
        doCopy(time, (x, y) -&gt; {
            y.setEat(x.getEat());
            y.setTitle(x.getTitle());
            y.setAge(x.getAge());
        }, <span class="hljs-string">"getter/setter"</span>);
    }
}

<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doCopy</span><span class="hljs-params">(Integer time, BeanCopy beanCopy, String type)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    <span class="hljs-keyword">long</span> startTime = System.currentTimeMillis();
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j &lt; time; j++) {
        SourceBean sourceBean = <span class="hljs-keyword">new</span> SourceBean(j, <span class="hljs-string">"source"</span> + j, <span class="hljs-keyword">false</span>, <span class="hljs-string">"abc"</span>);
        DstBean dstBean = <span class="hljs-keyword">new</span> DstBean();
        beanCopy.copy(sourceBean, dstBean);
    }
    System.out.printf(<span class="hljs-string">"执行%d次用时%dms---------%s%n"</span>, time, System.currentTimeMillis() - startTime, type);
}

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">BeanCopy</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">copy</span><span class="hljs-params">(SourceBean from, DstBean to)</span> <span class="hljs-keyword">throws</span> Exception</span>;
}

}

执行结果如下

结论

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

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

Bean拷贝工具类性能比较

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值