这是一份非常实用的 Lombok 教程,让你在10分钟内掌握这个能极大提升开发效率的工具。
一、Lombok 是什么?
Lombok 是一个 Java 库,通过注解的方式自动生成代码(如 getter、setter、构造函数等),让你的代码更简洁、更优雅。
核心价值:减少样板代码,提高开发效率。
二、环境搭建
1. 添加依赖
Maven:
XML
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 使用最新版本 -->
<scope>provided</scope>
</dependency>
Gradle:
bash
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
}
2. IDE 安装插件
-
IntelliJ IDEA: 安装 "Lombok" 插件
-
Eclipse: 下载 Lombok jar 包,双击运行安装
-
VS Code: 安装 "Lombok" 扩展
3. 开启注解处理
在 IDEA 中:Settings → Build → Compiler → Annotation Processors → Enable annotation processing
三、核心注解详解
1. @Data - 万能注解
作用 :自动生成 getter、setter、toString()、equals()、hashCode() 和全参构造函数。
使用前:
java
public class User {
private Long id;
private String name;
private Integer age;
private String email;
// 需要手动写一大堆方法...
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// ... 省略其他 getter/setter
@Override
public String toString() { ... }
@Override
public boolean equals(Object o) { ... }
@Override
public int hashCode() { ... }
}
使用后:
java
import lombok.Data;
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
// 所有方法自动生成!
2. @Getter / @Setter - 单独的 getter/setter
java
import lombok.Getter;
import lombok.Setter;
public class User {
@Getter @Setter private Long id;
@Getter(AccessLevel.PROTECTED)
private String password; // 只有 protected 的 getter
@Setter(AccessLevel.NONE)
private String readonlyField; // 没有 setter
}
3. 构造函数注解
java
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
@NoArgsConstructor // 无参构造函数
@AllArgsConstructor // 全参构造函数
@RequiredArgsConstructor // 针对 final 字段和 @NonNull 字段的构造函数
public class User {
private Long id;
private final String type; // final 字段会被包含在 @RequiredArgsConstructor 中
@NonNull private String name; // @NonNull 字段也会被包含
private Integer age;
}
4. @ToString - 自动生成 toString
java
import lombok.ToString;
@ToString(exclude = {"password"}, callSuper = true)
public class User {
private Long id;
private String name;
private String password; // 排除在 toString 之外
}
// 生成:User(super=Object@1234, id=1, name=张三)
5. @EqualsAndHashCode - 相等性判断
java
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(exclude = {"createTime"}, callSuper = true)
public class User {
private Long id;
private String name;
private Date createTime; // 排除在 equals 和 hashCode 计算之外
}
6. @Builder - 建造者模式
使用前:
java
User user = new User();
user.setId(1L);
user.setName("张三");
user.setAge(25);
user.setEmail("zhangsan@example.com");
使用后:
java
import lombok.Builder;
@Builder
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
// 使用建造者模式
User user = User.builder()
.id(1L)
.name("张三")
.age(25)
.email("zhangsan@example.com")
.build();
7. @Slf4j - 日志记录
使用前:
java
public class UserService {
private static final Logger log = LoggerFactory.getLogger(UserService.class);
public void addUser(User user) {
log.info("添加用户: {}", user.getName());
// 业务逻辑
}
}
使用后:
java
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UserService {
public void addUser(User user) {
log.info("添加用户: {}", user.getName());
// 业务逻辑
}
}
四、实用组合示例
1. JPA 实体类
java
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import javax.persistence.*;
@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_name", nullable = false)
private String name;
private Integer age;
private String email;
}
2. Spring Service 类
java
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
public User createUser(User user) {
log.info("创建用户: {}", user.getName());
User savedUser = userRepository.save(user);
emailService.sendWelcomeEmail(savedUser.getEmail());
return savedUser;
}
}
3. 配置类
java
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "app.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
private int maxPoolSize = 10;
private int minIdle = 2;
}
五、进阶用法
1. 静态构造方法
java
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StringUtils {
public static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
// 无法实例化:StringUtils utils = new StringUtils(); // 编译错误
}
2. 懒加载
java
import lombok.Getter;
public class ExpensiveService {
@Getter(lazy = true)
private final ExpensiveObject expensiveObject = createExpensiveObject();
private ExpensiveObject createExpensiveObject() {
// 昂贵的初始化操作
return new ExpensiveObject();
}
}
// 只有在第一次调用 getExpensiveObject() 时才会初始化
3. val - 局部变量类型推断
java
import lombok.val;
import java.util.ArrayList;
public class Example {
public void example() {
val list = new ArrayList<String>(); // 自动推断为 ArrayList<String>
list.add("hello");
for (val item : list) { // 自动推断为 String
System.out.println(item.toUpperCase());
}
}
}
六、与 MapStruct 配合使用
Lombok 与 MapStruct(对象映射工具)是绝佳组合:
java
// 实体类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
}
// DTO 类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
private Long id;
private String name;
private Integer age;
private String status; // 额外字段
}
// Mapper 接口
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDTO toDTO(User user);
User toEntity(UserDTO userDTO);
}
七、常见问题与解决方案
1. IDEA 报错但编译正常
-
检查 Lombok 插件是否安装
-
开启注解处理:Settings → Build → Compiler → Annotation Processors
2. 继承问题
java
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AdminUser extends User {
private String role;
// 包含父类的字段在 equals、hashCode、toString 中
}
3. 循环依赖
java
@Data
public class Department {
private String name;
private List<Employee> employees;
}
@Data
public class Employee {
private String name;
private Department department; // 循环依赖!
// 解决方案:在 toString 和 equals 中排除
@ToString.Exclude
@EqualsAndHashCode.Exclude
private Department department;
}
4. 不可变对象
java
@Value // 相当于 final @ToString @EqualsAndHashCode @AllArgsConstructor @Getter @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class ImmutableUser {
Long id;
String name;
Integer age;
}
// 所有字段都是 final 的,只有 getter,没有 setter
八、最佳实践
-
实体类 :使用
@Data+@Builder+@NoArgsConstructor+@AllArgsConstructor -
Service 类 :使用
@Slf4j+@RequiredArgsConstructor -
工具类 :使用
@NoArgsConstructor(access = AccessLevel.PRIVATE) -
配置类 :使用
@Data+@ConfigurationProperties -
避免过度使用:在需要大量样板代码的地方使用 Lombok