zoukankan      html  css  js  c++  java
  • Java对象属性复制备忘

    基于面向对象和各种设计要求,一个分层的Java系统中存在各种 VO、DTO、BO、PO 之类的对象,同一个实体的不同对象需要大量的属性复制,为了避免手动操作,需要一种便捷对象浅复制工具类,下面是各个常见工具对比。

    列举

    //cglib
    net.sf.cglib.beans.BeanCopier.create 
    net.sf.cglib.beans.BeanCopier.copy
    
    //spring-beans
    org.springframework.beans.BeanUtils.copyProperties
    
    //commons-beanutils
    org.apache.commons.beanutils.BeanUtils.copyProperties
    org.apache.commons.beanutils.PropertyUtils.copyProperties
    

    原理

    以上4种方式都是通过自动调用原对象的getter方法,再用目标对象的setter方法设置进去,区别在于BeanCopier先通过create创建了一个以BeanCopier派生的动态代理类,其创建的copy方法实现包含以上所有getter和setter的调用过程,调用copy可以达到原生代码方式的性能;而其他所有方式如spring-beans和commons-beanutils的实现都是通过反射逐个调用getter和setter,性能相比前者较差。

    细节

    细节 Apache-PropertyUtils Apache-BeanUtils Spring-BeanUtils Cglib-BeanCopier
    相同属性名,不同类型转换Converter扩展 NO Yes Yes Yes,较难用,需要对每一种属性类型都做转换
    相同属性名,Integer和int的处理 OK OK OK 不拷贝,忽略该属性
    相同属性名,Long和Integer的处理 异常报错 OK,自动互转 不拷贝,忽略该属性 不拷贝,忽略该属性
    对基本类型null值处理(Integer,Long等) OK 特殊,会将null转为0,用Converter后解决 OK OK
    对source特殊属性的限制:(Date,BigDecimal等) OK NO,异常出错,必须用Converter才行 OK OK
    Get和set方法不匹配的处理 OK,忽略该属性 OK,忽略该属性 OK,忽略该属性 创建异常(仅限source有get方法在target中找不到对应set方法)
    调用异常处理 需处理异常 需处理异常 RuntimeException RuntimeException

    需要兼容性的场景,优先spring-beans提供的BeanUtils,功能强大,兼容性最好。需要性能的场景,优先选择cglib提供的BeanCopier,性能最好(注意需要缓存create结果)。

    还有一项需要注意的是所有拷贝都是浅拷贝,注意属性引用不变,避免新老对象同时读写引起问题,这需要通过场景约束。

    结论

    事实上,由于不同工具类实现不同,细节差异非常多,一个团队最好通过规范统一使用某一个,并对其熟悉和理解,不必追求万能的工具类。我在新项目中选择了BeanCopier,并通过场景和限制约定避免踩坑。

    • 场景约束:主要用于同模型的DO、DTO和VO等之间转换。
    • 限制约定:要求两者同名属性具有严格相同类型,且其getter和setter一一对应,不能包含特殊逻辑。
  • 相关阅读:
    Vue SSR 配合Java的Javascript引擎j2v8实现服务端渲染4支持构建bundle
    Vue SSR 配合Java的Javascript引擎j2v8实现服务端渲染3配置webpack支持ssr
    使用graalvm.js调用promise
    backup
    使用babel与@babel/node
    Vue SSR 配合Java的Javascript引擎j2v8实现服务端渲染2创建Vue2+webpack4项目
    Vue SSR配合Java的Javascript引擎j2v8实现服务端渲染1概述
    CSS图片垂直居中
    Yarn && npm设置镜像源
    Spring 使用介绍(八)—— 零配置(一)
  • 原文地址:https://www.cnblogs.com/pyx0/p/copy-properties.html
Copyright © 2011-2022 走看看