1. 概述
Project Lombok 是一个消除样板代码的利器,让我们能更专注于核心业务逻辑。
同样,MapStruct 也是一个在 Java Bean 之间做映射时减少样板代码的库。
本文将探讨如何高效地结合使用这两个工具。
2. 环境配置
在 pom.xml
中添加以下依赖:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.6.0.Beta2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
⚠️ 注意:lombok-mapstruct-binding
是关键依赖,确保两个注解处理器能正确协同工作。
3. MapStruct 与 Lombok 集成实践
我们将重点使用 Lombok 的 @Builder
和 @Data
注解:
@Builder
:通过建造者模式创建对象@Data
:自动生成 getter/setter 等基础方法
3.1. Java POJO 定义
先定义一个简单的源对象:
@Data
public class SimpleSource {
private String name;
private String description;
}
再定义两个目标对象,分别使用不同注解:
@Data
public class SimpleDestination {
private String name;
private String description;
}
@Builder
@Getter
public class LombokDestination {
private String name;
private String description;
}
3.2. 使用 @Mapper 注解
MapStruct 会根据 @Mapper
注解自动生成实现类。定义映射接口:
@Mapper
public interface LombokMapper {
SimpleDestination sourceToDestination(SimpleSource source);
LombokDestination sourceToLombokDestination(SimpleSource source);
}
执行 mvn clean install
后,在 /target/generated-sources/annotations/
目录下生成实现类:
public class LombokMapperImpl implements LombokMapper {
@Override
public SimpleDestination sourceToDestination(SimpleSource source) {
if ( source == null ) {
return null;
}
SimpleDestination simpleDestination = new SimpleDestination();
simpleDestination.setName( source.getName() );
simpleDestination.setDescription( source.getDescription() );
return simpleDestination;
}
@Override
public LombokDestination sourceToLombokDestination(SimpleSource source) {
if ( source == null ) {
return null;
}
LombokDestination.LombokDestinationBuilder lombokDestination = LombokDestination.builder();
lombokDestination.name( source.getName() );
lombokDestination.description( source.getDescription() );
return lombokDestination.build();
}
}
关键差异点:
✅ SimpleDestination
:通过构造函数创建 + setter 赋值
✅ LombokDestination
:通过 builder()
方法链式调用构建
3.3. 测试验证
@Test
void whenDestinationIsMapped_thenIsSuccessful() {
SimpleSource simpleSource = new SimpleSource();
simpleSource.setName("file");
simpleSource.setDescription("A text file.");
SimpleDestination simpleDestination = lombokMapper.sourceToDestination(simpleSource);
Assertions.assertNotNull(simpleDestination);
Assertions.assertEquals(simpleSource.getName(), simpleDestination.getName());
Assertions.assertEquals(simpleSource.getDescription(), simpleDestination.getDescription());
LombokDestination lombokDestination = lombokMapper.sourceToLombokDestination(simpleSource);
Assertions.assertNotNull(lombokDestination);
Assertions.assertEquals(simpleSource.getName(), lombokDestination.getName());
Assertions.assertEquals(simpleSource.getDescription(), lombokDestination.getDescription());
}
测试结果验证了两种映射方式都能正确转换对象属性。
4. 总结
通过本文实践,我们实现了:
- 减少样板代码:Lombok 自动生成基础方法,MapStruct 自动生成映射逻辑
- 提升代码可读性:声明式映射替代手写转换逻辑
- 开发效率提升:两个工具协同工作,避免重复劳动
关键踩坑点:
- 务必添加
lombok-mapstruct-binding
依赖 @Builder
和@Data
生成的代码结构不同,MapStruct 会自动适配
完整代码示例可在 GitHub 获取。