关于 lombok
lombok 是面向 Java 开发者的参考技能,汇总常用注解、配置示例和故障排查建议。内容涵盖样板代码生成、构造器、Builder、日志及实体类使用注意事项。
主要功能
- 01介绍常用 Lombok 注解
- 02提供 Maven 配置示例
- 03展示实体类与 DTO 模式
- 04说明日志和资源清理用法
- 05列出常见问题与反模式
适用场景
- 01为 Java 类生成访问器或构造器
- 02使用 Builder 构建对象
- 03在服务类中配置 SLF4J 日志
- 04排查注解处理或生成代码问题
MCP 相关
README 提到可通过 mcp__documentation__fetch_docs 获取 Lombok 的详细文档;未说明其他 MCP 能力。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ claude-dev-suite/ claude-dev-suite --skill lombok安装后在 Claude Code 中输入/lombok确认已加载。
详细介绍
Project Lombok
深入了解:使用
mcp__documentation__fetch_docs,并将 technology 设为lombok,获取完整文档。
Maven 配置
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</dependency>
常用注解
@Data(一站式)
@Data
public class User {
private Long id;
private String name;
private String email;
}
// Generates:
// - @Getter for all fields
// - @Setter for all non-final fields
// - @ToString
// - @EqualsAndHashCode
// - @RequiredArgsConstructor
@Getter / @Setter
public class User {
@Getter @Setter
private String name;
@Getter // Read-only
private final String email;
@Setter(AccessLevel.PROTECTED)
private String internalId;
}
@NoArgsConstructor / @AllArgsConstructor / @RequiredArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String name;
}
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository; // Included in constructor
private final UserMapper userMapper; // Included in constructor
private String cacheName; // NOT included
}
@Builder
@Data
@Builder
public class User {
private Long id;
private String name;
private String email;
@Builder.Default
private UserStatus status = UserStatus.ACTIVE;
}
// Usage
User user = User.builder()
.name("John")
.email("[email protected]")
.build();
// With toBuilder for updates
User updated = user.toBuilder()
.name("Jane")
.build();
@Value(不可变)
@Value
public class UserResponse {
Long id;
String name;
String email;
LocalDateTime createdAt;
}
// Generates:
// - All fields are private final
// - @AllArgsConstructor
// - @Getter (no setters)
// - @ToString
// - @EqualsAndHashCode
实体模式
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@EntityListeners(AuditingEntityListener.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(unique = true, nullable = false)
private String email;
@Enumerated(EnumType.STRING)
@Builder.Default
private UserStatus status = UserStatus.ACTIVE;
@CreatedDate
@Column(updatable = false)
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
// Exclude from toString/equals for performance
@ToString.Exclude
@EqualsAndHashCode.Exclude
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
}
使用构造器注入的服务模式
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
private final PasswordEncoder passwordEncoder;
@Override
public UserResponse create(CreateUserRequest dto) {
log.info("Creating user: {}", dto.getEmail());
User user = userMapper.toEntity(dto);
return userMapper.toResponse(userRepository.save(user));
}
}
日志记录
@Slf4j // SLF4J logger
public class UserService {
public void process() {
log.info("Processing...");
log.debug("Debug info: {}", data);
log.error("Error occurred", exception);
}
}
@Log4j2 // Log4j2 logger
@CommonsLog // Apache Commons Logging
@JBossLog // JBoss Logging
DTO 模式
// Request DTO
@Data
public class CreateUserRequest {
@NotBlank
private String name;
@Email
private String email;
@Size(min = 8)
private String password;
}
// Response DTO (immutable)
@Value
@Builder
public class UserResponse {
Long id;
String name;
String email;
UserStatus status;
LocalDateTime createdAt;
}
@Cleanup
public void readFile(String path) throws IOException {
@Cleanup InputStream in = new FileInputStream(path);
// in.close() called automatically
}
@SneakyThrows
@SneakyThrows // Wraps checked exception
public String readConfig() {
return Files.readString(Path.of("config.json"));
}
@Synchronized
public class Counter {
@Synchronized
public void increment() {
// Thread-safe
}
}
@With(不可变更新)
@Value
@With
public class Point {
int x;
int y;
}
Point p1 = new Point(1, 2);
Point p2 = p1.withX(5); // Point(5, 2)
关键注解
| 注解 | 用途 |
|---|---|
@Data | Getter、Setter、ToString、Equals、Constructor |
@Value | 不可变类 |
@Builder | 构建器模式 |
@RequiredArgsConstructor | 为 final 字段生成构造器 |
@Slf4j | Logger 字段 |
@ToString.Exclude | 从 toString 中排除 |
@EqualsAndHashCode.Exclude | 从 equals/hashCode 中排除 |
不应使用此技能的场景
| 场景 | 改用 |
|---|---|
| Java 核心语言 | java 技能 |
| MapStruct 映射 | mapstruct 技能 |
| Spring 注解 | backend-spring-boot 技能 |
| 包含复杂逻辑的 JPA 实体 | 手动实现 |
| 公共 API 设计 | 使用显式方法以提高清晰度 |
反模式
| 反模式 | 问题 | 正确做法 |
|---|---|---|
| 在 JPA 实体上使用 @Data | toString/equals 问题 | 有选择地使用 @Getter/@Setter |
| 未排除延迟加载关联 | LazyInitializationException | 使用 @ToString.Exclude |
| 在实体上使用 @EqualsAndHashCode | 代理问题 | 使用 @EqualsAndHashCode(onlyExplicitlyIncluded = true) |
| 到处使用 @SneakyThrows | 隐藏异常 | 使用恰当的异常处理 |
| 使用 @Builder 但未使用 @Default | 字段为 null | 添加 @Builder.Default |
| @Value 搭配可变字段 | 破坏不可变性 | 仅使用不可变类型 |
| 混用 @Data 和手动编写的方法 | API 令人困惑 | 保持一致 |
| 未在 lombok.config 中配置 | 行为不一致 | 使用 lombok.config 文件 |
快速故障排除
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Getter 报错“Cannot find symbol” | IDE 未处理注解 | 启用注解处理 |
| LazyInitializationException | 对延迟加载关联调用 toString | 添加 @ToString.Exclude |
| MapStruct 无法运行 | 处理器顺序错误 | 将 Lombok 放在 MapStruct 之前 |
| Builder 缺少字段 | 未使用 @Builder.Default | 添加默认值或检查配置 |
| equals 中出现 StackOverflowError | 循环引用 | 排除关联字段 |
| IDE 显示错误但编译成功 | IDE 缓存 | 清除缓存并重启 |
| 找不到 @Slf4j 日志记录器 | classpath 中没有 SLF4J | 添加 SLF4J 依赖 |
| 看不到生成的代码 | 需要 delombok | 运行 delombok 任务 |
参考文档
深入了解:使用
mcp__documentation__fetch_docs,并将 technology 设为lombok,获取完整文档。
评论
支持 Markdown