BeanCopier_contabo测评

2022-10-04 09:10:39 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

概述

常见或常用的几种Bean属性复制工具

  • Apache.BeanUtils
  • Apache.PropertyUtil
  • Spring.BeanUtils
  • Cglib.BeanCopier
  • MapStruct
  • EZMorph

使用场景:Dto与Entity转换

  • 普通属性复制
  • 个别属性过滤
  • 属性类型转换
  • 数组或集合拷贝

性能对比

测试在两个简单的Bean之间转换的耗时,执行次数分别为10、100、1k、10k、100k,时间单位为ms。


源码分析

Apache.BeanUtils

org.apache.commons.beanutils

  1. 通过内省(Introspector)获取源类型的属性信息
  2. 判断源类型的属性是否可读及目标类型的属性是否可写
    • 可读
      • 有getter方法
    • 可写
      • 有setter方法
  3. 进行复制
    1. 获取属性名
    2. 获取属性类型
    3. 进行属性值转类型[自带类型转换器,提供注册自定义转换器接口]
    4. 赋值

执行过程

  1. 获取工具实例,调用属性复制方法
  1. 获取实例方法
  1. 实例获取的函数是同步的,因为ContextClassLoader的不同,每个线程都会创建一个实例
  1. 属性复制函数:先是空值的判断,然后通过Java内省机制获取属性描述,判断属性是否可读/可写,然后通过反射赋值

发现在初始化过程中,BeanUtils实例的获取是“假单例”模式,每个线程拥有一个BeanUtils实例,所以每个线程每次初始化都消耗资源。


Apache.PropertyUtils

org.apache.comons.beanutils

使用内省,操作getter/setter方法。基本流程同Apache.BeanUtils

区别

BeanUtils支持属性类型转换,而PropertyUtils不支持,若有同名不同类型的属性,则会报错。

BeanUtils自带类型转换器,支持如下类型转换:

  • java.lang.BigDecimal
  • java.lang.BigInteger
  • boolean and java.lang.Boolean
  • byte and java.lang.Byte
  • char and java.lang.Character
  • java.lang.Class
  • double and java.lang.Double
  • float and java.lang.Float
  • int and java.lang.Integer
  • long and java.lang.Long
  • short and java.lang.Short
  • java.lang.String
  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp

Springframework.beans.BeanUtils

org.springframework.beans.BeanUtils

Spring的BeanUtils也是通过java内省机制获取getter/setter,然后通过反射调用从而实现属性复制,但区别于Apache的BeanUtils,Spring的BeanUtils为单例模式,不需要重复创建。同时,Spring.BeanUtils支持忽略属性。


Cglib BeanCopier

net.sf.cglib.beans

使用动态代理,生成字节码类,再通过Java反射成Class,调用其copy方法。

执行过程

  • 创建BeanCopier

[使用了缓存,该过程也消耗资源,建议全局只初始化一次]

通过字节码生成了两个类

  • KeyFactory
  • BeanCopier

  • 调用copy方法。

(支持自定义类型转换器) 【有convert的情况】

【无convert的情况】

生成的BeanCopier里面直接使用Bean的setter/getter


MapStruct

org.mapstrcut.*

http://mapstruct.org/ 支持XML配置和注解配置

使用示例

  • 自定义Mapper类
  • 编译生成实现类
  • Bean复制

EZMorph

性能感人,不做深究。

也是通过反射


功能维度对比

根据属性复制工具的功能维度对工具进行分析,对比如下:

  • Apache.BeanUtils
  • Apache.PropertyUtil
  • Spring.BeanUtils
  • Cglib.BeanCopier
  • MapStruct
  • EZMorph

总结

根据不同工具的性能及功能维度,个人建议当对象转换操作较少或者应用对性能要求较高时,尽量不采用工具,而是手写getter/setter;在不考虑性能的情况下,普通的对象转换可以使用Cglib.BeanCopier,复杂的对象转换使用MapStruct。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

0 人点赞