java bean属性拷贝工具类比对(性能+功能)
业务系统中经常需要两个对象进行属性的拷贝,不能否认逐个的对象拷贝是最快速最安全的做法,但是当数据对象的属性字段数量超过程序员的容忍的程度比如通常超过5个属性的时候,代码因此变得臃肿不堪,使用一些方便的对象拷贝工具类将是很好的选择。
目前流行的较为公用认可的工具类:
Apache的两个版本:(反射机制)
org.apache.commons.beanutils.PropertyUtils.copyProperties(Object dest, Object orig)
org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest, Object orig)
Spring版本:(反射机制)
org.springframework.beans.BeanUtils.copyProperties(Object source, Object target, Class editable, String[] ignoreProperties)
新版本的spring也集成了cglib版:org.springframework.cglib.beans.BeanCopier
cglib版本:(使用动态代理,效率高)
net.sf.cglib.beans.BeanCopier.copy(Object paramObject1, Object paramObject2, Converter paramConverter)
dozer版本(xml配置映射,性能最低下):
就API而言,使用哪个工具类无所谓,我们通常关心两点,功能完善性以及性能。
性能测试:
// 源POJO package tf56.lf.lfbase.model.dto; import java.io.Serializable; import tf56.lf.lfbase.model.domain.LfProduct; /** * ClassName:ProductDTO * * @version 1.0 * @since v1.0 * @Date 2017年6月19日 yuebiao.wu */ public class ProductDTO extends LfProduct implements Serializable{ private static final long serialVersionUID = -1296801547926874402L; } // 目标POJO package tf56.lf.lfbase.model.domain; import java.io.Serializable; import java.util.Date; import lombok.Getter; import lombok.Setter; /** * ClassName:Product * * @author tool * @version 1.0 * @since v1.0 * Date Jun 26, 2017 2:40:42 PM */ @Getter @Setter public class LfProduct implements Serializable { private static final long serialVersionUID = 4054863309367744108L; /* 产品id */ private String lfProductId; /* 物流金融账号 */ private String lfAccountId; /* 产品名称 */ private String productName; /* 产品类型(BAOFU:保付; MIAOFU:秒付; JISHIFU:即时付;) */ private String productType; /* 适用场景列表(逗号分隔)(COD:代收货款; FREIGHT:运费;) */ private String sceneTypes; /* 产品描述 */ private String productDescription; /* 产品规则描述 */ private String productRoleDescription; /* 放款触发行为 */ private String loanAction; /* 收款触发行为 */ private String repayAction; /* 产品状态(ENABLE:启用; DISABLE:停用;) */ private String productStatus; /* 预警阀值 */ private Long warnBalance; /* 发货人是否控制额度(1:是; 0:否;) */ private Integer isConsignerCreditLimit; /* 承运商是否控制额度(1:是; 0:否;) */ private Integer isExpressCreditLimit; private String productAgreementUrl; private String poundageCalcType; private String poundageRate; /* 备注1 */ private String remark1; /* 操作员编号 */ private String operatorId; /* 输入日期 */ private Date inputDate; /* 记录更新时间 */ private Date stampDate; }
BeanCopier
Mapper wrapper = new DozerBeanMapper(); ProductDTO pdt = new ProductDTO(); pdt.setIsConsignerCreditLimit(3); pdt.setLoanAction("323f3"); pdt.setProductName("feiwefe"); pdt.setPoundageRate("f332r3"); long beg = System.currentTimeMillis(); PropertyUtilsBean bean = new PropertyUtilsBean(); BeanCopier copier = BeanCopier.create(ProductDTO.class, LfProduct.class, false); for (int i=0;i<1000;i++) { LfProduct lfPdt = new LfProduct(); // try { // try { // bean.copyProperties(lfPdt, pdt); // } catch (IllegalAccessException | InvocationTargetException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } catch (NoSuchMethodException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } copier.copy(pdt, lfPdt, null); if (i==3) { // System.out.println(JacksonHelper.toJSON(lfPdt)); } // lfPdt = wrapper.map(pdt, LfProduct.class); lfPdt.setInputDate(new Date()); } System.out.println(System.currentTimeMillis() - beg);
大约140ms左右。
Mapper wrapper = new DozerBeanMapper(); ProductDTO pdt = new ProductDTO(); pdt.setIsConsignerCreditLimit(3); pdt.setLoanAction("323f3"); pdt.setProductName("feiwefe"); pdt.setPoundageRate("f332r3"); long beg = System.currentTimeMillis(); PropertyUtilsBean bean = new PropertyUtilsBean(); BeanCopier copier = BeanCopier.create(ProductDTO.class, LfProduct.class, false); for (int i=0;i<1000;i++) { LfProduct lfPdt = null; // try { // try { // bean.copyProperties(lfPdt, pdt); // } catch (IllegalAccessException | InvocationTargetException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } catch (NoSuchMethodException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // copier.copy(pdt, lfPdt, null); if (i==3) { // System.out.println(JacksonHelper.toJSON(lfPdt)); } lfPdt = wrapper.map(pdt, LfProduct.class); lfPdt.setInputDate(new Date()); } System.out.println(System.currentTimeMillis() - beg);
2500ms。
PropertyUtilsBean
Mapper wrapper = new DozerBeanMapper(); ProductDTO pdt = new ProductDTO(); pdt.setIsConsignerCreditLimit(3); pdt.setLoanAction("323f3"); pdt.setProductName("feiwefe"); pdt.setPoundageRate("f332r3"); long beg = System.currentTimeMillis(); PropertyUtilsBean bean = new PropertyUtilsBean(); BeanCopier copier = BeanCopier.create(ProductDTO.class, LfProduct.class, false); for (int i=0;i<1000;i++) { LfProduct lfPdt = new LfProduct(); try { try { bean.copyProperties(lfPdt, pdt); } catch (IllegalAccessException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } // copier.copy(pdt, lfPdt, null); if (i==3) { // System.out.println(JacksonHelper.toJSON(lfPdt)); } // lfPdt = wrapper.map(pdt, LfProduct.class); lfPdt.setInputDate(new Date()); } System.out.println(System.currentTimeMillis() - beg);
240ms左右。
所以,因为绝大部分都是简单的复制拷贝,这种情况下,BeanCopyer>PropertyUtils>Dozer。
参考:
http://blog.csdn.net/jianhua0902/article/details/8155368
http://blog.csdn.net/liangrui1988/article/details/41802275
相关文章
- java 反射机制--根据属性名获取属性值
- Java 集合框架06---Map的架构
- java利用Tesseract 识别身份证号码
- java基础-关键字-native
- 通过java类的反射机制获取类的属性类型
- Effective Java 第三版——35. 使用实例属性替代序数
- Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性
- 【Java 问题 & 解决方法 · SpringBoot & Jackson】Enum类型 转JSON无法获取内部属性
- java中遍历实体类属性和类型,属性值
- 国内最火的10款Java开源项目,都是国人开发,CMS居多
- restclient 访问 springmvc java工程接口
- FastJson只序列化java对象的部分属性
- Java 毫秒转换为日期类型、日期转换为毫秒
- Java中各种(类、方法、属性)访问修饰符与修饰符的说明
- Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别
- Java SE1.6中的Synchronized
- Java入门 Vector类
- 使用引用类型变量来访问所引用对象的属性和方法时,Java 虚拟机绑定规则
- Android JNI访问Java成员
- Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap
- JAVA多线程实现的三种方式
- JAVA实现RSA加密,非对称加密算法
- Java继承中属性、方法和对象的关系
- Java jdk11 在Mac上的安装和配置以及JDK多个版本之间切换
- Teach Yourself Java 2 in 21 Days 书中样例代码实践
- 为什么新出的《阿里Java开发手册》都要读一读?
- Java虚拟机(JVM)你只要看这一篇就够了!