Lombok和MapStruct整合
一、先上操作流程
1、安装Lombok插件,(2020.0.4之后版本的IDEA已内置Lombok,老版本的请自行下载插件)
2、打开setting -> enable annotation processor (启用注解处理器)
OK 完事~ 可以使用了 送上常用四件套
@Data //生成Getter 、Setter 、ToString 、ToString 、EqualsAndHashCode
@AllArgsConstructor //全参构造
@NoArgsConstructor //无参构造
@Builder //构建器,可以链式构建对象(想build父类请用@SuperBuilder)
可以自行在classes里看生成的代码
二、正常来说到这就结束了,但是。。。在Lombok和MapStruct一起使用时就会有一些冲突
说明一下:
Lombok和MapStruct都是用来简化Java代码的组件,它可以通过AnnotationProcessor在编译时自动生成代码,简化了我们日常开发。
同时,由于是编译时生成的class文件,从安全性和性能角度考虑也会比运行时的工具好很多,例如BeanUtil.copy()
原理:
自从Java 6起,javac就支持“JSR 269 Pluggable Annotation Processing API”规范,只要程序实现了该API,就能在javac运行的时候得到调用。 lombok本质上就是这样的一个实现了"JSR 269 API"的程序。在使用javac的过程中,它产生作用的具体流程如下:
- javac对源代码进行分析,生成一棵抽象语法树(AST)
- 运行过程中调用实现了"JSR 269 API"的lombok程序
- 此时lombok就对第一步骤得到的AST进行处理,找到@Data注解所在类对应的语法树(AST),然后修改该语法树(AST),增加getter和setter方法定义的相应树节点
- javac使用修改后的抽象语法树(AST)生成字节码文件
原因:
因为他们他们都是编译时通过AnnotationProcessor生成的class文件,然后MapStruct会用到对象中的get、set方法,然后get、set方法又需要lombok来生成。所以我们需要空着这两者工作顺序。
解决办法:
lombok 1.18.16之前,添加path
lombok 1.18.16之后,添加path,必须使用 lombok-mapstruct-binding 插件。
本着用新不用旧的想法我选了第二种
三、Mapstruct中使用lombok@Builder的坑
场景:
当mapstruct转化的对象使用了lombok的@Builder注解时,没法创建父类对象的值。
原因:
当mapstruct的转化对象使用了@Builder,会默认使用builder去构建对象。然而lombok的builder中没有父类属性,因此无法赋值
解决方案:
-
让mapstruct不使用Builder构建对象(@Mapper)
mapstruct上在@Mapper注解中标注不使用builder
@Mapper(builder = @Builder(disableBuilder = true))
-
让lombok能够在builder使用父类属性(@SuperBuilder)
使用lombok的POJO上及其父类使用@SuperBuilder注解,此方案受限于通常公司的一些公共的基类上没法去修改。
@SuperBuilder
-
去掉POJO上的@Builder
这样的话mapstruct就会先构建无参构造,再去逐个set的方式去赋值。
参考:
转载自:https://juejin.cn/post/7099874296373182478