性能对比
工具名称
执行100次耗时
10000次
100000次
1000000次
Apache BeanUtils
347ms
606ms
2345ms
12552ms
DozerBeanMapper
241ms
456ms
1538ms
8273ms
Spring BeanUtils
71ms
164ms
146ms
640ms
Cglib BeanCopier
60ms
102ms
120ms
239ms
Selma
3ms
12ms
35ms
57ms
MapStruct
1ms
3ms
7ms
13ms
手动Bean创建
<1ms
2ms
6ms
12ms
不要用Apache BeanUtils.copyProperties
结论
运行期通过反射调用set/get 或者是直接对成员变量赋值。该方式通过invoke执行赋值,实现时一般会采用BeanUtils, Javassist等开源库。这类的代表:Dozer, BeanUtils。
编译期通过动态生成set/get代码的class文件,在运行时直接调用该class文件。该方式和Lombok一样,会存在set/get代码,只是不需要自己写了。 这类的代表:MapStruct, Selma。
实验证明 手动Bean创建 > MapStruct > Selma > Cglib BeanCopier > Spring BeanUtils > DozerBeanMapper > Apache BeanUtils
建议使用MapStruct或者手动创建Copy。
Apache BeanUtils
Spring BeanUtils
Apache BeanUtils 中copyProperty主要集中了各种丰富的功能(日志、转换、解析等等),导致性能变差。
而Spring BeanUtils则是直接通过反射来读取和写入,省去了其他繁杂的步骤。
MapStruct Demo
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
}