java 代码生成器 MapStruct
2023/5/8 18:00:00 【次浏览】 本站
MapStruct
MapStruct是干什么的?
MapStruct是个代码产生器,它能直接根据注解生成 Java 对象对应的转换器。
比如,直接把一个 A 类型的 Java 对象,给转成 B 类型的 Java 对象,只需要在他们之间配置上字段之间的映射关系即可。
为什么在项目里用它?
现在随便一个项目都是多层的,尤其是 Web 项目,经常需要在多层之间做对象模型转换,比如 DTO 转换成 BO。
DTO(Data Transfer Object):数据传输对象,Service 向外传输的对象。
BO(Business Object):业务对象,由 Service 层输出的封装业务逻辑的对象。
但是这种转换工作就像是小时候,老师罚我们抄写名人名言 100 遍一样,十分枯燥,还容易出错。
像这样:
public class CarMapper {CarDto carDoToCarDto(Car car) {CarDto carDto = new CarDto();carDto.setCarId(car.getCarId());carDto.setWheel(car.getWheel());carDto.setCarType(car.getCarType());carDto.setCarColor(car.getCarColor());......}}
要是 Car 有几十个字段,像 Car 一样的又有几十个类,你可以想一下,这种繁琐程度。
在 MapStruct 之前,我们都是通过 Apache 或者 Spring 的 BeanUtils 工具,去自动做这种事情。
但是这类工具有两个问题:
1.性能比较差
性能差主要是 Apache 的 BeanUtils 这套东西,它每次都要针对字段,做是否可读写的检查,还要根据字段生成对应的 PropertyDescriptor。
这些严重影响了它的性能,所以,在阿里 Java 手册里,也不推荐用它。
Spring 的 BeanUtils,虽然精简了很多 Apache 的 BeanUtils 的读写检查以及对应的属性信息记录,但是它依然是通过反射调用,而且是大量反射调用。这种性能也不能令人满意。
2.运行期做转换,出错就代表损失
BeanUtils 这类工具,有个统一的名称,叫做 Java 对象映射框架。
它们大部分的实现都是在运行期去执行代码,然后在 Java 对象之间去拷贝对应的值。
运行期间做这种事儿,有个最大的问题——整个项目启动运行后,才能发现错误。比如,转换的时候,类型不一致导致报错。
对于此种情况,咱们大家都知道,这事儿就像开业酬宾没搞好,变成了开业仇宾……
如果能写完代码,编译的时候就发现问题,这种损失就可以避免了。
MapStruct 的引入就是为了解决以上这两个问题。
MapStruct 首先是个代码产生器,它是根据注解,去产生一个专门用来转换的工具类,这个工具类,就像我们自己写的 Java 类一样,可以直接被使用,这样就避免了反射。
同时,它产生的转换类也特别简单,就是默认会在两个类型的 Java 对象之间,拷贝同名属性的值。
如果有了配置,属性不同名也可以拷贝。所以它的性能很好。
示例代码如下:
@Mapper public interface CarMapper {CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );@Mapping(target = "seatCount", source = "numberOfSeats")CarDto carBoToCarDto(Car car); }
MapStruct由于是个代码产生器,就带来了个巨大的好处,就是这家伙是在编译阶段就会生成对应的类,所以,如果有了类似类型转换不过去的问题,直接就编译报错了,根本等不到运行才发现。这样的话,就不会造成什么损失,这真是件十分 Nice 的事情。
代码库地址
https://github.com/mapstruct/mapstruct
手机扫码查看当前文章: