Lombok 新手教程
这是一份非常实用的 Lombok 教程,让你在10分钟内掌握这个能极大提升开发效率的工具。
一、Lombok 是什么?
Lombok 是一个 Java 库,通过注解的方式自动生成代码(如 getter、setter、构造函数等),让你的代码更简洁、更优雅。
核心价值:减少样板代码,提高开发效率。
二、环境搭建
1. 添加依赖
Maven:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version> <!-- 使用最新版本 --><scope>provided</scope>
</dependency>Gradle:
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() 和全参构造函数。
使用前:
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@Overridepublic String toString() { ... }@Overridepublic boolean equals(Object o) { ... }@Overridepublic int hashCode() { ... }
}使用后:
import lombok.Data;@Data
public class User {private Long id;private String name;private Integer age;private String email;
}
// 所有方法自动生成!2. @Getter / @Setter - 单独的 getter/setter
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. 构造函数注解
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
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 - 相等性判断
import lombok.EqualsAndHashCode;@EqualsAndHashCode(exclude = {"createTime"}, callSuper = true)
public class User {private Long id;private String name;private Date createTime; // 排除在 equals 和 hashCode 计算之外
}6. @Builder - 建造者模式
使用前:
User user = new User();
user.setId(1L);
user.setName("张三");
user.setAge(25);
user.setEmail("zhangsan@example.com");使用后:
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 - 日志记录
使用前:
public class UserService {private static final Logger log = LoggerFactory.getLogger(UserService.class);public void addUser(User user) {log.info("添加用户: {}", user.getName());// 业务逻辑}
}使用后:
import lombok.extern.slf4j.Slf4j;@Slf4j
public class UserService {public void addUser(User user) {log.info("添加用户: {}", user.getName());// 业务逻辑}
}四、实用组合示例
1. JPA 实体类
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 类
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. 配置类
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. 静态构造方法
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. 懒加载
import lombok.Getter;public class ExpensiveService {@Getter(lazy = true)private final ExpensiveObject expensiveObject = createExpensiveObject();private ExpensiveObject createExpensiveObject() {// 昂贵的初始化操作return new ExpensiveObject();}
}
// 只有在第一次调用 getExpensiveObject() 时才会初始化3. val - 局部变量类型推断
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) { // 自动推断为 StringSystem.out.println(item.toUpperCase());}}
}六、与 MapStruct 配合使用
Lombok 与 MapStruct(对象映射工具)是绝佳组合:
// 实体类
@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. 继承问题
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AdminUser extends User {private String role;// 包含父类的字段在 equals、hashCode、toString 中
}3. 循环依赖
@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.Excludeprivate Department department;
}4. 不可变对象
@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+@AllArgsConstructorService 类:使用
@Slf4j+@RequiredArgsConstructor工具类:使用
@NoArgsConstructor(access = AccessLevel.PRIVATE)配置类:使用
@Data+@ConfigurationProperties避免过度使用:在需要大量样板代码的地方使用 Lombok
