几种Bean的复制方法性能比较

  由于项目对性能 速度要求很高,表中的字段也很多,存在一个复制方法,耗时相对比较长,经过测试,使用Apache,Spring等提供的方法 耗时较长,使用自己自定义的复制方法时间提升很多,现记录下。

1.pom.xml

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 2   <modelVersion>4.0.0</modelVersion>
 3   <groupId>com.xsjt.compare</groupId>
 4   <artifactId>copy-property</artifactId>
 5   <version>0.0.1-SNAPSHOT</version>
 6
 7   <dependencies>
 8       <!-- apache -->
 9     <dependency>
10         <groupId>commons-beanutils</groupId>
11         <artifactId>commons-beanutils</artifactId>
12         <version>1.8.3</version>
13     </dependency>
14
15       <!-- Spring -->
16     <dependency>
17         <groupId>org.springframework</groupId>
18         <artifactId>spring-beans</artifactId>
19         <version>4.3.8.RELEASE</version>
20     </dependency>
21
22     <!-- cglib -->
23     <dependency>
24         <groupId>cglib</groupId>
25         <artifactId>cglib</artifactId>
26         <version>3.2.3</version>
27     </dependency>
28
29     <!-- ezmorph -->
30     <dependency>
31         <groupId>net.sf.ezmorph</groupId>
32         <artifactId>ezmorph</artifactId>
33         <version>1.0.6</version>
34     </dependency>
35
36   </dependencies>
37 </project>

2.定义一个实体bean

 1 package com.xsjt.bean;
 2
 3 import java.io.Serializable;
 4 import java.math.BigDecimal;
 5 import java.util.Date;
 6
 7 /**
 8  * 用户实体类
 9  * @author Administrator
10  *
11  */
12 @SuppressWarnings("serial")
13 public class User implements Serializable{
14
15     private int id;
16     private String userName;
17     private String userPass;
18     private String phone;
19     private Date birth;
20     private BigDecimal totleMoney;
21     private String remark;
22
23     public User() {
24         super();
25     }
26
27     public User(int id, String userName, String userPass, String phone, Date birth, BigDecimal totleMoney, String remark) {
28         super();
29         this.id = id;
30         this.userName = userName;
31         this.userPass = userPass;
32         this.phone = phone;
33         this.birth = birth;
34         this.totleMoney = totleMoney;
35         this.remark = remark;
36     }
37
38     public int getId() {
39         return id;
40     }
41     public void setId(int id) {
42         this.id = id;
43     }
44     public String getUserName() {
45         return userName;
46     }
47     public void setUserName(String userName) {
48         this.userName = userName;
49     }
50     public String getUserPass() {
51         return userPass;
52     }
53     public void setUserPass(String userPass) {
54         this.userPass = userPass;
55     }
56     public String getPhone() {
57         return phone;
58     }
59     public void setPhone(String phone) {
60         this.phone = phone;
61     }
62     public Date getBirth() {
63         return birth;
64     }
65     public void setBirth(Date birth) {
66         this.birth = birth;
67     }
68     public BigDecimal getTotleMoney() {
69         return totleMoney;
70     }
71     public void setTotleMoney(BigDecimal totleMoney) {
72         this.totleMoney = totleMoney;
73     }
74     public String getRemark() {
75         return remark;
76     }
77     public void setRemark(String remark) {
78         this.remark = remark;
79     }
80
81     @Override
82     public String toString() {
83         return "User [id=" + id + ", userName=" + userName + ", userPass=" + userPass + ", phone=" + phone + ", birth=" + birth + ", totleMoney=" + totleMoney + ", remark=" + remark + "]";
84     }
85
86 }

3.自己定义的bean复制方法

 1 package com.xsjt.util;
 2
 3 import java.lang.reflect.Field;
 4 import java.math.BigDecimal;
 5 import java.util.Date;
 6 import com.xsjt.bean.User;
 7
 8 /**
 9  * ClassName:CopyBeanProperty
10  * 在对象之间 进行属性值 复制
11  * Date:     2017年7月19日 下午5:53:07
12  * @author   Joe
13  * @version
14  * @since    JDK 1.8
15  */
16 public class CopyBeanProperty {
17
18     /**
19      * 将 旧的bean的值 赋值 给 新的bean
20      * @param oldObj
21      * @param newObj
22      */
23     public static void copyproperty(Object oldObj ,Object newObj){
24
25         Class<?> clz = oldObj.getClass();
26         Field[] cols = clz.getDeclaredFields();
27
28         String name = null;
29         Object value = null;
30         try {
31             for(Field col : cols){
32                 if(!col.isAccessible()){
33                     // 设置可访问
34                     col.setAccessible(true);
35                 }
36                 name = col.getName();
37                 value = col.get(oldObj);
38                 // 赋值给 新的bean
39                 setBeanProperty(name ,value ,newObj);
40             }
41         } catch (Exception e) {
42             e.printStackTrace();
43         }
44     }
45
46     /**
47      * 将 name 和  value 赋值给 新的bean
48      * @param name
49      * @param value
50      * @param newObj
51      * @throws SecurityException
52      * @throws NoSuchFieldException
53      * @throws IllegalAccessException
54      * @throws IllegalArgumentException
55      */
56     private static void setBeanProperty(String name, Object value, Object newObj) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
57         Class<?> clz = newObj.getClass();
58         Field col = clz.getDeclaredField(name);
59         if(!col.isAccessible()){
60             // 设置可访问
61             col.setAccessible(true);
62         }
63         col.set(newObj, value);
64     }
65
66     /**
67      * 循环输入 属性 和 值 ,测试的 时候 使用
68      * @param newObj
69      * @throws IllegalAccessException
70      * @throws IllegalArgumentException
71      */
72     private static void loopBeanProperty(Object newObj) throws IllegalArgumentException, IllegalAccessException{
73         Class<?> clz = newObj.getClass();
74         Field[] cols = clz.getDeclaredFields();
75         for(Field col : cols){
76             if(!col.isAccessible()){
77                 // 设置可访问
78                 col.setAccessible(true);
79             }
80             System.out.println(col.getName() + "-->" + col.get(newObj));
81         }
82     }
83
84     /**
85      * 测试
86      * @param args
87      */
88     public static void main(String[] args) {
89         User user = new User(1, "admin", "12345", "135555555555", new Date(), new BigDecimal(20000.88), "土豪");
90         try {
91             loopBeanProperty(user);
92         } catch (IllegalArgumentException e) {
93             e.printStackTrace();
94         } catch (IllegalAccessException e) {
95             e.printStackTrace();
96         }
97     }
98 }

4.各种bean复制方法的比较

 1 package com.xsjt.compare;
 2
 3 import java.math.BigDecimal;
 4 import java.util.Date;
 5 import org.apache.commons.beanutils.BeanUtils;
 6 import com.xsjt.bean.User;
 7 import com.xsjt.util.CopyBeanProperty;
 8 import net.sf.cglib.beans.BeanCopier;
 9 import net.sf.ezmorph.MorpherRegistry;
10 import net.sf.ezmorph.bean.BeanMorpher;
11
12 /**
13  * ClassName:CompareTest
14  * 测试 各种 复制 方法的性能
15  * Date:     2017年7月19日 下午5:53:07
16  * @author   Joe
17  * @version
18  * @since    JDK 1.8
19  */
20 public class CompareTest {
21
22     public static void main(String[] args) throws Exception {
23
24         // 1.使用 apache 的 复制 方法
25         User orig = new User(1, "admin", "12345", "135555555555", new Date(), new BigDecimal(20000.88), "土豪");
26         User dest = new User();
27         long start = System.currentTimeMillis();
28         BeanUtils.copyProperties(dest, orig);
29         System.out.println("1.apache的方法 花费的时间:" + (System.currentTimeMillis() - start) + "ms");
30         System.out.println("dest==" + dest);
31
32         System.out.println("--------------------------------我是分割线------------------------------------------------");
33
34         // 2.使用 spring 的 复制方法
35         User source = new User(1, "admin", "12345", "135555555555", new Date(), new BigDecimal(20000.88), "土豪");
36         User target = new User();
37         start = System.currentTimeMillis();
38         org.springframework.beans.BeanUtils.copyProperties(source, target);
39         System.out.println("2.spring的方法 花费的时间:" + (System.currentTimeMillis() - start) + "ms");
40         System.out.println("target==" + target);
41
42         System.out.println("--------------------------------我是分割线------------------------------------------------");
43
44         // 3.使用 cglib 的复制方法
45         User source2 = new User(1, "admin", "12345", "135555555555", new Date(), new BigDecimal(20000.88), "土豪");
46         User target2 = new User();
47         start = System.currentTimeMillis();
48         BeanCopier.create(source2.getClass(), target2.getClass(), false).copy(source2, target2, null);
49         System.out.println("3.cglib的方法 花费的时间:" + (System.currentTimeMillis() - start) + "ms");
50         System.out.println("target2==" + target2);
51
52         System.out.println("--------------------------------我是分割线------------------------------------------------");
53
54         // 4.使用 EZMorph 的复制方法
55         User source3 = new User(1, "admin", "12345", "135555555555", new Date(), new BigDecimal(20000.88), "土豪");
56         User target3 = new User();
57         start = System.currentTimeMillis();
58         MorpherRegistry registry = new MorpherRegistry();
59         registry.registerMorpher(new BeanMorpher(User.class, registry));
60         target3 = (User) registry.morph(User.class, source3);
61         System.out.println("4.EZMorph的方法 花费的时间:" + (System.currentTimeMillis() - start) + "ms");
62         System.out.println("target3==" + target3);
63
64         System.out.println("--------------------------------我是分割线------------------------------------------------");
65
66         // 5.使用 自定义 的复制方法
67         User oldUser = new User(1, "admin", "12345", "135555555555", new Date(), new BigDecimal(20000.88), "土豪");
68         User newUser = new User();
69         start = System.currentTimeMillis();
70         CopyBeanProperty.copyproperty(oldUser, newUser);
71         System.out.println("5.自定义的方法 花费的时间:" + (System.currentTimeMillis() - start) + "ms");
72         System.out.println("newUser==" + newUser);
73     }
74 }

5.运行结果展示

  

  自定义的复制方法,使用了Java的反射机制实现,虽然其他的方法也是通过反射实现。但是自己定义的耗时时间最少,记录下,以备后用。

6.源码下载

  https://git.oschina.net/xbq8023/copy-property.git

时间: 2024-12-15 10:55:02

几种Bean的复制方法性能比较的相关文章

【进阶EJB】深入探讨三种Bean(三)——MessageDriven Bean

通过前两篇文文章 [进阶EJB]深入探讨三种Bean(一)--Session Bean [进阶EJB]深入探讨三种Bean(二)--Entity Bean 已经介绍了前两种Bean,今天我们继续介绍第三种Bean--MessageDriven Bean. 要说MessageDriven Bean前就先要介绍一下JMS(Java Message Service),JMS是Java消息服务,它是一个与具体平台无关的API(Application Program Interface 应用程序接口),是

Go_18: Golang 中三种读取文件发放性能对比

Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提供的 read 方法进行读取 下面通过代码来验证这三种方式的读取性能,并总结出我们平时应该使用的方案,以便我们可以写出最优代码: package main import ( "os" "io" "bufio" "io/ioutil"

【进阶EJB】深入探讨三种Bean(二)——Entity Bean

通过上一篇文章,我们介绍了[进阶EJB]深入探讨三种Bean(一)--Session Bean,这篇文章继续介绍EJB的三种Bean,今天我们重点介绍一下Entity Bean. Entity Bean,通过名字我们就知道是实体Bean是存放数据的.Entity Bean是持久化的数据组件,代表持久存储的商业实体对象.通常情况下,每个Entity Bean对应于关系数据库中的单张表,Entity Bean的单个实例对应于表中的某一条数据.上篇文章中说的Session Bean可作为Entity

几种流行Webservice框架性能对照

 转自[http://blog.csdn.net/thunder4393/article/details/5787121],写的非常好,以收藏. 1      摘要 开发webservice应用程序中离不开框架的支持,当open-open站点列举的就有30多种,这对于开发人员怎样选择带来一定的疑惑.性能Webservice的关键要素,不同的框架性能上存在较大差异,而当前在官方站点.网络资料中能够方便的找到各自框架的介绍,可是非常少有针对不同框架性能測试数据.本文选择了比較流行几个框架:Apach

【进阶EJB】深入探讨三种Bean(一)——Session Bean

接着,我们继续EJB的学习.经过前两篇博客的介绍,我想大家已经对EJB有了一个初步的认识.但是大家想过没有,我们为什么要用EJB呢? why EJB? 其中一个很重要的原因就是分布式!所谓分布式,就是分布式对象之间相互协作,完成特定的业务功能.通俗一点来说,就是我们不是把事情交给一个人去做,而是把事情划分一下,交给多个人去处理,最后把多个人处理的结果综合在一起得到最终的结果.与此同时,分布式对象之间能够实现分布透明性,亦或是位置透明性,即在客户端代码中无需指定分布式对象的位置:而且分布式对象之间

Golang 中三种读取文件发放性能对比

Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提供的 read 方法进行读取 下面通过代码来验证这三种方式的读取性能,并总结出我们平时应该使用的方案,以便我们可以写出最优代码: package main import ( "os" "io" "bufio" "io/ioutil"

5种提升SQL查询性能的知识

“SQL性能优化是一种黑魔法就像炼金术一样:各种配方难解晦涩,只有一小部分圈内人才能理解.” 这是一种误解,SQL数据库使用的是大家公知的算法来实现可以预期的执行性能.然而,问题是,人们很容易写出不能发挥最高效算法的SQL查询语句,因而也容易产生无法预期的性能结果. 下面是5道关于SQL性能优化小测试题,这些测试题也许会让你坚信SQL优化就是一种黑魔法.但答案中提供的解释说明会随即让你明白,这些所谓的黑魔法其实是纯粹的科学. 本测试中使用的SQL是基于Oracle数据库. 单从性能的视角看,下面

java解析xml文件四种方式介绍、性能比较和基本使用方法

一.介绍: 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作.由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的.DOM以及广义的基于树的处理具有几个优点.首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改.它还可以在任何时候在树中上下导航,而不

从SqlSessionFactoryBean的引用浅谈spring两种bean模式

mybatis是以一个 SqlSessionFactory 的实例为中心的.SqlSessionFactory可以通过SqlSessionFactoryBuilder获得实例.使用mybatis-spring时,session创建,可以让SqlSessionFactoryBean来替代. <bean name="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">