首页 > 代码库 > 几种Bean的复制方法性能比较

几种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>
View Code

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 Administrator10  *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     @Override82     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:CopyBeanProperty10  * 在对象之间 进行属性值 复制 11  * Date:     2017年7月19日 下午5:53:0712  * @author   Joe  13  * @version    14  * @since    JDK 1.815  */16 public class CopyBeanProperty {17     18     /**19      * 将 旧的bean的值 赋值 给 新的bean20      * @param oldObj21      * @param newObj22      */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 = http://www.mamicode.com/null;30         try {31             for(Field col : cols){32                 if(!col.isAccessible()){33                     // 设置可访问34                     col.setAccessible(true);35                 }36                 name = col.getName();37                 value =http://www.mamicode.com/ col.get(oldObj);38                 // 赋值给 新的bean39                 setBeanProperty(name ,value ,newObj);40             }41         } catch (Exception e) {42             e.printStackTrace();43         }44     }45 46     /**47      * 将 name 和  value 赋值给 新的bean48      * @param name49      * @param value50      * @param newObj51      * @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 newObj69      * @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 args87      */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:CompareTest14  * 测试 各种 复制 方法的性能15  * Date:     2017年7月19日 下午5:53:0716  * @author   Joe  17  * @version    18  * @since    JDK 1.819  */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

 

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