我是 ABin-阿斌:写一生代码,创一世佳话,筑一览芳华。 如果小伙伴们觉得我的文章不错,记得一键三连哦
文章目录
- 一、mapstruct简介
- 二、mapstruct与其他映射对比
- 三、mapstruct底层原理解析
- 1、Java动态编译
- 四、具体使用
- 1、依赖导入
- 2、定义一个用例映射的接口
- 场景一:
- 场景二:
- 场景三:
- 参考文章:
一、mapstruct简介
- mapstruct是一种 实体类 映射框架,能够通过Java注解将一个实体类的属性安全地赋值给另一个实体类。有了mapstruct,只需要定义一个映射器接口,声明需要映射的方法,在编译过程中,mapstruct会自动生成该接口的实现类,实现将源对象映射到目标对象的效果。
二、mapstruct与其他映射对比
- 实体类映射框架大致有两种:一种是运行期通过java反射机制动态映射;另一种是编译期动态生成getter/setter,在运行期直接调用框架编译好的class类实现实体映射。
- 由于mapstruct映射是在编译期间实现的,因此相比运行期的映射框架有以下几个优点:
- 安全性高。因为是编译期就实现源对象到目标对象的映射, 如果编译器能够通过,运行期就不会报错。
- 速度快。速度快指的是运行期间直接调用实现类的方法,不会在运行期间使用反射进行转化。
三、mapstruct底层原理解析
- mapstruct是基于JSR 269实现的,JSR 269是JDK引进的一种规范。有了它,能够实现在编译期处理注解,并且读取、修改和添加抽象语法树中的内容。JSR 269使用Annotation Processor在编译期间处理注解,Annotation Processor相当于编译器的一种插件,因此又称为插入式注解处理。想要实现JSR 269,主要有以下几个步骤:
- 继承AbstractProcessor类,并且重写process方法,在process方法中实现自己的注解处理逻辑。
- 在META-INF/services目录下创建javax.annotation.processing.Processor文件注册自己实现的Annotation Processor
1、Java动态编译
Java程序编译一般经历以下流程:
上图中Java源码到class文件的过程其实是一个比较复杂的过程。其中的经过可以用下图描述:
上图的流程可以概括为下面几个步骤:
- 生成抽象语法树。Java编译器对Java源码进行编译,生成抽象语法树(Abstract Syntax Tree,AST)。
- 调用实现了JSR 269 API的程序。只要程序实现了JSR 269 API,就会在编译期间调用实现的注解处理器。
- 修改抽象语法树。在实现JSR 269 API的程序中,可以修改抽象语法树,插入自己的实现逻辑。
- 生成字节码。修改完抽象语法树后,Java编译器会生成修改后的抽象语法树对应的字节码文件件。
四、具体使用
1、依赖导入
- 首先需要把依赖包导入,主要由两个包组成:
- org.mapstruct:mapstruct:
- 包含了一些必要的注解,例如 @Mapping。r若我们使用的 JDK 版本高于1.8,当我们在pom里面导入依赖时候,建议使用坐标是:org.mapstruct:mapstruct-jdk8,这可以帮助我们利用一些 Java8 的新特性。
- org.mapstruct:mapstruct-processor:
- 注解处理器,根据注解自动生成 mapper 的实现。
- org.mapstruct:mapstruct:
<properties>
<!-- 版本依赖 -->
<mapstruct.version>1.4.2.Final</mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
2、定义一个用例映射的接口
- 在实体类下面创建即可,方便查找
场景一:
- 如果返回的参数属性名称与映射不同,那么我们就要映射成原有的
场景二:
- 可以使用表达式来获取自己想要的信息
- 比如:这里我们想要获取工具类的某个方法,那么就可以使用这种表达式
场景三:
- ignore: 表示忽略映射当前字段
参考文章:
- https://juejin.cn/post/6956190395319451679
- https://www.cnblogs.com/mmzs/p/12735212.html