BeanUtils.copyProperties知多少?

事出有因

近期在读《阿里巴巴开发手册》的时候发现:阿里强制避免使用BeanUtils进行属性的拷贝,但是不得不承认的是,在我自己的项目中确实使用过Apache的Beanutils进行属性拷贝,在读了开发手册后,感觉项目中的代码可以优化一下,基于不同包下的BeanUtils性能和特性有所不同,当然用法也不尽相同,所以,可以你可能会跳入因为导错包导致对象拷贝为null的坑。

浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。(类似a对象的指针指到了b)

深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象

比物连类

目前已有其他大佬对Apache、Spring的工具类进行了数据对比:详细请看:

几种copyProperties工具类性能比较

借用大佬的数据说明下结果:

工具名称执行1000次耗时10000次100000次1000000次
Apache BeanUtils390ms854ms1763ms8408ms
Apache PropertyUtils26ms221ms352ms2663ms
spring BeanUtils39ms315ms373ms949ms
Cglib BeanCopier64ms144ms171ms309ms

Apache的BeanUtils去拷贝属性时,性能是最慢的,数据拷贝皆使用Java的反射实现,Apache比较慢的原因是:

  • 进行大量参数校验
  • 使用解析类型转换

Apache源码

Apache源码

spring中的BeanUtils去拷贝属性时就是对两个对象中相同名字的属性进行简单get/set,仅检查属性的可访问性。实现的方式没有太复杂的逻辑,代码执行较快。

物尽其用

在使用BeanUtils时,会先引用对应的包,如果包引用不对的话,就可能会跳入开头的大坑中,具体如下:

org.apache.commons.beanutils.BeanUtils

BeanUtils.copyProperties(a,b);
b的值赋值a

org.springframework.beans.BeanUtils

BeanUtils.copyProperties(a,b);
a的值赋给b
归根结蒂

正如上文的测试数据,如果不是阿里级别的并发量、数据量,其实三种工具类的性能差距是感知力不强的,倒不如去优化SQL对性能来的实在,但是既然有了更好的选择,仅仅是导入不同的包,参数位置的不同而已,如果属性值比较少,没必要使用属性拷贝,直接手动get/set即可。所以,代码中我们尽量使用性能较高且可行的方案。重要的是对于代码的责任心和负责度,正如雷军先生说过的那样:我们要像写诗一样写代码,尽量使代码更加优雅。所以,我推荐MapStruct

ps:请MapStruct把我的广告费结一下
别开生面

分布式项目中,不同的应用与应用之间,还有单独的应用细分模块之后,DO 一般不会让外部依赖,这时候需要在提供对外接口的模块里放 DTO 用于对象传输,也即是 DO 对象对内,DTO对象对外,DTO 可以根据业务需要变更,并不需要映射 DO 的全部属性。这种 对象与对象之间的互相转换,就需要有一个专门用来解决转换问题的工具,毕竟每一个字段都 get/set 会很麻烦。我在跟前阿里员工合作的时候,属性转换使用的是MapStruct,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值