几种Bean的复制方法性能比较
Posted 听歌敲代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了几种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/xbq168/copy-property.git
以上是关于几种Bean的复制方法性能比较的主要内容,如果未能解决你的问题,请参考以下文章