前言
也不知道说啥,那就直入主题吧~
什么是MapStruct?
介绍
相信大家,已经在各种地方都听过MapStruct
这个框架了,知道它是一个类似于BeanUtils
的拷贝框架,那么下面让我们来看下官方的介绍
MapStruct is a Java annotation processor for the generation of type-safe and performant mappers for Java bean classes. It saves you from writing mapping code by hand, which is a tedious and error-prone task. The generator comes with sensible defaults and many built-in type conversions, but it steps out of your way when it comes to configuring or implementing special behavior.
翻译一下就是:MapStruct是一个基于Java编译期注解处理器来实现,用来高性能、类型安全的生成Java bean的映射器。可以避免我们手动写Getter/Getter等映射代码。
在上面的介绍中可以发现一个词Java annotation processor
,翻译成中文就是Java编译期注解处理器
,那么什么是Java编译期注解处理器呢?
Java编译处理器(APT)
Java编译时期处理器可以简称为APT
,它是Javac
的工具,最早出现在JDK5
的版本中,随后在之后的版本不断新增相关API,开始流行起来。
通过APT
可以拿到注解和被注解对象的相关信息,随后通过自身需求来自动生成一些代码,避免手动编写。例如我们常用的Lombok
就有采用APT
来生成相关代码。
同时,获取注解和自定义生成代码等操作都是在编译期完成的,不会影响运行时期的程序性能。不过有一点需要注意,APT
只能用于生成新文件,不能更改现有的文件。
基本原理
通过官方介绍已经知道MapStruct
是通过Java编译期注解处理器也就是APT
来实现的。那么具体是怎么样实现的呢?
- 实现一个APT首先需要继承
AbstractProcessor
或者实现Processor
接口,基本都是继承抽象类来实现的。 - 随后在创建
META-INF/services/javax.annotation.processing.Processor
文件,并在里面注册自定义的Annotation Processor
。
通过查看[MapStruct](mapstruct/mapstruct: An annotation processor for generating type-safe bean mappers (github.com))的源码,就可以发现它定义了一个MappingProcessor
的类同时继承了AbstractProcessor
来实现相应功能。并在javax.annotation.processing.Processor
文件中注册了MappingProcessor
类。
MapStruct
的具体怎么生成Mapper实现类
先不鸟他,下面就来看看怎么使用吧~
优缺点
在使用前,先来看一波MapStruct
的优缺点,在实践中就能切身体会到优缺点拉。
先吹优点:
- 高性能映射对象,相关于反射来实现的性能快将近20倍,差不多很接近原生的Getter/Setter方法。如果想要看具体性能比较可以参考这篇文章Performance of Java Mapping Frameworks | Baeldung。
- 编译时期安全,不会出现错误对象的映射,例如不会出现将
商品
映射成用户DTO。
- 仅在编译时期工作,不会有运行期依赖
那么代价是啥捏?就我个人而言认为缺点只有一个:繁琐
,相关于常用Spring中的BeanUtils
编写较为繁琐,会增加工作量,不能够准时下班拉。
那么下面就来通过实例来了解MapStruct吧
如何简单使用
环境配置
- Jdk11
- MapStruct 1.5.0.RC1
需要注意一点,MapStruct
只支持1.8或者更高的版本。
Maven配置:
...
<properties>
<org.mapstruct.version>1.5.0.RC1</org.mapstruct.version>
</properties>
...
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin<