上一篇《基于注解进行对象拷贝(一)》,评论中有人推荐MapStruct这个类库,有必要了解下这个类库。
MapStruct
介绍
MapStruct本质上是一个注解处理器,在编译阶段根据我们定义的接口生成具体的实现类,进行拷贝时直接使用方法调用的方式(与基于反射的方式有明显区别),因此速度更快,也是类型安全的(在编译时期就生成相应的转换方法)。
详细说明可以参考官网
使用方法
基于1.3.1.Final版本,官网上给出了一个简单的入门教程,可以了解MapStruct的使用方法。
默认隐式类型转换
- 基本类型以及对应的包装类型
- 数字类型之间(注意精度问题)
- 基本类型以及对应的包装类型和String之间
- 枚举类型和String
- 大数字类型(
BigInteger,BigDecimal)和基本类型(以及对应包装类型)、String - 时间格式之间
实现方法
通过继承javax.annotation.processing包中的AbstractProcessor接口,可以让我们能够在编译期间通过注解处理器进行我们需要的操作,比较常见的用法就是在编译期间获取相关注解数据,动态生成.java类型的源文件,自动产生一些有规律性的重复代码,解决了手工编写重复代码的问题。
代码生成工具
MapStruct使用freemarker生成.java文件,在之前的demo基础上,可以看一下MapStruct生成代码的例子。
CarMapper接口
package org.cloud.mapstruct;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car);
}
MapStruct生成结果
可以在target/generated-sources/annotations下面进行查看
package org.cloud.mapstruct;
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2020-08-03T15:34:24+0800",
comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_231 (Oracle Corporation)"
)
public class CarMapperImpl implements CarMapper {
@Override
public CarDto carToCarDto(Car car) {
if ( car == null ) {
return null;
}
CarDto carDto = new CarDto();
carDto.setSeatCount( car.getNumberOfSeats() );
carDto.setMake( car.getMake() );
carDto.setType( String.valueOf( car.getType() ) );
return carDto;
}
}