经验专题-Bean拷贝-1、原理对比
1. 特性
https://segmentfault.com/a/1190000040106844
https://cloud.tencent.com/developer/article/1624695
Spring.BeanUtils:是浅拷贝,不支持深拷贝
Apache.BeanUtils:是浅拷贝,不支持深拷贝
BeanCopier:是浅拷贝,不支持深拷贝。BeanCopier 的实现原理跟 BeanUtils 截然不同,它不是利用反射对属性进行赋值,而是直接使用 cglib 来生成带有的 get/set 方法的 class 类,然后执行。由于是直接生成字节码执行,所以 BeanCopier 的性能接近手写
BeanUtils 和 BeanCopier 都是功能比较简单的,需要属性名称一样,甚至类型也要一样。
Dozer:是深拷贝。Dozer 的实现原理本质上还是用反射/Introspector 那套
Orika:是深拷贝。底层使用 Javassist
生成字节码
JMapper:未知
MapStruct:是浅拷贝,不支持深拷贝。MapStruct 是一个自动生成 bean mapper 类的代码生成器
ModelMapper:是浅拷贝,不支持深拷贝
1.1. 选择
http://18965050.github.io/work/orika
如果不需要深拷贝,就用 MapStruct
如果需要深拷贝,就用 Orika 或者用插件生成(如 coding-wizard)
2. 原理对比
目前常用的属性拷贝工具,包括 Apache 的 BeanUtils、Spring 的 BeanUtils、Cglib 的 BeanCopier、mapstruct。
2.1. Apache BeanUtils:BeanUtils
Apache commons 组件里面的成员,由 Apache 提供的一套开源 api,用于简化对 javaBean 的操作,能够对基本类型自动转换。
循环遍历源对象的每个属性,对于每个属性,拷贝流程为:
- 校验来源类的字段是否可读 isReadable
- 校验目标类的字段是否可写 isWriteable
- 获取来源类的字段属性值 getSimpleProperty
- 获取目标类字段的类型 type,并进行类型转换
- 设置目标类字段的值
由于单字段拷贝时每个阶段都会调用 PropertyUtilsBean.getPropertyDescriptor 获取属性配置,而该方法通过 for 循环获取类的字段属性,严重影响拷贝效率。
2.2. Spring BeanUtils
BeanUtils 是 spring 框架下自带的工具,在 org.springframework.beans 包下, spring 项目可以直接使用。
2.3. Cglib BeanCopier
cglib(Code Generation Library)是一个强大的、高性能、高质量的代码生成类库,BeanCopier 依托于 cglib 的字节码增强能力,动态生成实现类,完成对象的拷贝。
2.4. mapstruct
mapstruct 是一个 Java 注释处理器,用于生成类型安全的 bean 映射类,在构建时,根据注解生成实现类,完成对象拷贝。
性能调优-进阶-2、系统调优案例♨️3. 实战经验
4. 参考与感谢
https://www.51cto.com/article/741833.html