在软件开发过程中,尤其是在涉及到数据库操作层(DAO)和数据传输对象(DTO)之间数据转换的场景下,开发者经常面临实体(Entity)与DTO结构相似但不完全相同的情况。这时,手动编写属性复制代码(例如
b.set(a.get()))显得既繁琐又低效。为了解决这一问题,我们可以借助一系列对象映射框架来简化和优化开发流程。框架介绍
在众多的对象映射框架中,以下几个是开发者使用最为频繁的:
- Spring的BeanUtils.copyProperties:作为Spring框架的一部分,这个方法通过Java反射机制实现了源对象和目标对象属性的复制。它极大地简化了不同层之间对象属性的复制操作,有效提升了开发效率。官方文档提供了详细的使用说明。
- Apache的BeanUtils.copyProperties:这个方法属于Apache Commons BeanUtils库,它在对象属性复制方面提供了更大的灵活性,尤其是在处理类型不匹配的属性时。相比Spring版本,Apache的BeanUtils在类型转换上表现更为出色,尽管这可能对性能造成一定影响。
- Orika:这是一个专注于性能和灵活性的映射框架,能够处理复杂的映射需求,如深层映射和双向映射,而无需编写大量代码。Orika在功能和配置上都提供了比Apache和Spring更高级的选项。
- BeanCopier:作为CGLIB库的一部分,BeanCopier专注于在Java对象之间快速复制属性。CGLIB是一个被广泛应用于AOP框架、动态代理和属性复制等场景的高性能代码生成库。相较于使用
java.lang.reflect.Proxy,BeanCopier在执行速度和灵活性上具有显著优势。
- MapStruct:这是一个基于编译时代码生成的Java注解对象映射框架,它旨在通过减少手动编写的映射代码数量来提高开发效率,同时利用编译时代码生成技术提供更好的性能,并能在编译阶段发现潜在的错误。
性能考虑
对于这些框架的性能评估,GitHub上的项目Object-to-object mapping framework microbenchmark提供了一个很好的参考基准。该项目对比了多个框架的性能,通过结果可以发现手写set/get方法和MapStruct的性能相差无几,而Orika的性能则较差。


但是由于【Object-to-object mapping framework microbenchmark】中缺少了BeanUtils、BeanCopier,所以我这fork了项目,添加了这几个对比项。项目地址在【https://github.com/yibiner/java-object-mapper-benchmark】。
先来看下在我电脑上跑的压测情况:

可以看到:
1、手写set/get,MapStruct,Selma、JMapper性能相差不大,Orika的性能与他们对比确实差了不少。
2、Spring的BeanUtils性能比Apache好多了,确实应该尽量避免使用Apache的BeanUtils。
3、对于相同的框架,不同的写法也会导致性能差异比较大,比如图中几个Orika的对比。

不过新加的几个测试库或者函数有些区别,是没有通过所有测试用例的,如下图。不过应该不影响结论。


4、BeanCopier性能遥遥领先。

最后,在选择对象映射框架时,开发者应当综合考虑性能、灵活性和易用性,以适应项目的具体需求。每种框架在处理
null值和属性名类型约束上的差异,也是选择时需要注意的点。📎 其他资料
- 作者:Yibin
- 链接:https://yibin.dev/article/0da13059-22dd-456d-991e-cda9d1d21fd4
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章







