当前位置: 首页 > news >正文

Lombok使用指南

Lombok使用指南

目录

  1. 什么是Lombok
  2. 安装与配置
  3. Lombok的主要注解
  4. Lombok的优缺点
  5. 最佳实践
  6. 常见问题与解决方案
  7. 兼容性与IDE支持
  8. 实际应用场景
  9. 总结

什么是Lombok

Lombok是一个Java库,它通过注解的方式,帮助开发者减少样板代码的编写,如getter、setter、构造方法、equals、hashCode等方法。Lombok在编译时自动生成这些代码,使Java代码更加简洁、易读。

Lombok的工作原理

Lombok通过Java的注解处理器(Annotation Processor)在编译时自动生成代码。当Java编译器编译带有Lombok注解的类时,Lombok的注解处理器会拦截编译过程,分析注解,然后生成相应的代码。这些生成的代码会被编译到最终的class文件中,但在源代码中是不可见的。

为什么需要Lombok

在Java开发中,我们经常需要编写大量的样板代码,例如:

public class User {
    private Long id;
    private String username;
    private String password;
    
    // 构造函数
    public User() {}
    
    public User(Long id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
    
    // Getter和Setter方法
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    // equals和hashCode方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) &&
               Objects.equals(username, user.username) &&
               Objects.equals(password, user.password);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(id, username, password);
    }
    
    // toString方法
    @Override
    public String toString() {
        return "User{" +
               "id=" + id +
               ", username='" + username + '\'' +
               ", password='" + password + '\'' +
               '}';
    }
}

使用Lombok后,上面的代码可以简化为:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String username;
    private String password;
}

这样,我们就减少了大量的样板代码,使代码更加简洁、易读,同时也减少了出错的可能性。

安装与配置

Maven项目安装步骤

  1. 打开项目的pom.xml文件
  2. <dependencies>标签内添加以下依赖:
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.30</version>
        <scope>provided</scope>
    </dependency>
    
  3. 保存文件,Maven会自动下载依赖
  4. 如果使用IDE(如IntelliJ IDEA),需要安装Lombok插件:
    • 打开IDE设置(File > Settings)
    • 转到插件市场(Plugins)
    • 搜索"Lombok"并安装
    • 重启IDE

Gradle项目安装步骤

  1. 打开项目的build.gradle文件
  2. dependencies块中添加以下依赖:
    compileOnly 'org.projectlombok:lombok:1.18.30'
    annotationProcessor 'org.projectlombok:lombok:1.18.30'
    
  3. 保存文件,Gradle会自动下载依赖
  4. 同样需要安装IDE的Lombok插件

IDE配置步骤

IntelliJ IDEA配置
  1. 安装Lombok插件:

    • 打开IDE设置(File > Settings)
    • 转到插件市场(Plugins)
    • 搜索"Lombok"并安装
    • 重启IDE
  2. 启用注解处理:

    • 打开IDE设置(File > Settings)
    • 转到构建、执行、部署 > 编译器 > 注解处理器(Build, Execution, Deployment > Compiler > Annotation Processors)
    • 勾选"启用注解处理"(Enable annotation processing)
    • 点击应用(Apply)和确定(OK)
  3. 启用Lombok插件:

    • 打开IDE设置(File > Settings)
    • 转到插件 > 已安装(Plugins > Installed)
    • 找到Lombok插件,确保它已启用
Eclipse配置
  1. 安装Lombok插件:

    • 下载Lombok安装程序(https://projectlombok.org/setup/eclipse)
    • 运行安装程序,选择Eclipse安装目录
    • 重启Eclipse
  2. 启用注解处理:

    • 打开项目属性(右键点击项目 > Properties)
    • 转到Java编译器 > 注解处理(Java Compiler > Annotation Processing)
    • 勾选"启用项目特定设置"(Enable project specific settings)
    • 勾选"启用注解处理"(Enable annotation processing)
    • 点击应用(Apply)和确定(OK)

Lombok的主要注解

Lombok注解总览

注解功能描述
@Data生成所有字段的getter/setter、toString()、equals()和hashCode()方法,以及无参构造方法
@Getter生成所有字段的getter方法
@Setter生成所有字段的setter方法
@NoArgsConstructor生成无参构造方法
@AllArgsConstructor生成全参数构造方法
@Builder生成建造者模式
@Slf4j自动生成日志对象
@EqualsAndHashCode生成equals和hashCode方法
@ToString生成toString方法
@RequiredArgsConstructor生成包含所有标记为@NonNull或final字段的构造方法
@Value生成不可变类,所有字段都是private和final的
@SneakyThrows自动处理受检异常
@Accessors控制生成的访问器(getter/setter)的行为
@Builder.Default为@Builder生成的建造者设置默认值
@SuperBuilder处理继承关系中的建造者模式
@NonNull标记字段或参数不能为null
@Cleanup自动关闭资源
@Generated标记生成的代码
@UtilityClass生成工具类
@Experimental标记实验性功能
@Lombok自定义注解
@FieldNameConstants生成字段名称常量
@With生成不可变对象的with方法
@Log生成日志对象(通用)
@CommonsLog生成Apache Commons Logging日志对象
@Flogger生成Google Flogger日志对象
@JBossLog生成JBoss日志对象
@Log4j生成Log4j日志对象
@Log4j2生成Log4j2日志对象
@Slf4j生成SLF4J日志对象
@XSlf4j生成SLF4J扩展日志对象

1. @Data

最常用的注解,自动生成以下内容:

  • 所有字段的getter和setter方法
  • toString()方法
  • equals()和hashCode()方法
  • 无参构造方法
@Data
public class User {
    private Long id;
    private String username;
    private String password;
    private String email;
}

2. @Getter和@Setter

分别生成getter和setter方法,可以指定访问级别:

@Getter(AccessLevel.PUBLIC)
@Setter(AccessLevel.PROTECTED)
public class User {
    private Long id;
    private String username;
}

3. @NoArgsConstructor和@AllArgsConstructor

生成无参构造方法和全参数构造方法:

@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String username;
    private String password;
}

4. @Builder

生成建造者模式,方便创建对象:

@Builder
public class User {
    private Long id;
    private String username;
    private String password;
}

// 使用方式
User user = User.builder()
    .id(1L)
    .username("zhangsan")
    .password("123456")
    .build();

5. @Slf4j

自动生成日志对象,无需手动定义:

@Slf4j
public class UserService {
    public void createUser(User user) {
        log.info("Creating user: {}", user.getUsername());
        // 业务逻辑
        log.debug("User created successfully");
    }
}

6. @EqualsAndHashCode

生成equals和hashCode方法,可以指定包含或排除的字段:

@EqualsAndHashCode(of = {"id", "username"})
public class User {
    private Long id;
    private String username;
    private String password; // 不参与equals和hashCode计算
}

7. @ToString

生成toString方法,可以指定包含或排除的字段:

@ToString(exclude = {"password"})
public class User {
    private Long id;
    private String username;
    private String password; // 不会出现在toString结果中
}

8. @RequiredArgsConstructor

生成包含所有标记为@NonNull或final字段的构造方法:

@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
    @NonNull
    private String applicationName;
}

9. @Value

生成不可变类,所有字段都是private和final的:

@Value
public class UserDTO {
    Long id;
    String username;
    String email;
}

10. @SneakyThrows

自动处理受检异常,无需显式声明throws:

public class FileUtils {
    @SneakyThrows
    public static String readFile(String path) {
        return Files.readString(Paths.get(path));
    }
}

11. @Accessors

控制生成的访问器(getter/setter)的行为:

@Data
@Accessors(chain = true) // 支持链式调用
public class User {
    private Long id;
    private String username;
    private String password;
}

// 使用方式
User user = new User()
    .setId(1L)
    .setUsername("zhangsan")
    .setPassword("123456");

12. @Builder.Default

为@Builder生成的建造者设置默认值:

@Builder
public class User {
    private Long id;
    private String username;
    
    @Builder.Default
    private Integer status = 1; // 默认值为1
}

13. @SuperBuilder

处理继承关系中的建造者模式:

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class BaseEntity {
    private Long id;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class User extends BaseEntity {
    private String username;
    private String password;
    private String email;
}

// 使用方式
User user = User.builder()
    .id(1L)
    .createTime(LocalDateTime.now())
    .updateTime(LocalDateTime.now())
    .username("zhangsan")
    .password("123456")
    .email("zhangsan@example.com")
    .build();

14. @NonNull

标记字段或参数不能为null:

public class UserService {
    public void createUser(@NonNull User user) {
        // 方法实现
    }
}

15. @Cleanup

自动关闭资源:

public class FileUtils {
    public static void copyFile(String source, String target) {
        @Cleanup InputStream in = new FileInputStream(source);
        @Cleanup OutputStream out = new FileOutputStream(target);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = in.read(buffer)) > 0) {
            out.write(buffer, 0, length);
        }
    }
}

16. @With

生成不可变对象的with方法:

@With
@Value
public class User {
    Long id;
    String username;
    String email;
}

// 使用方式
User user = new User(1L, "zhangsan", "zhangsan@example.com");
User updatedUser = user.withEmail("new@example.com"); // 创建新对象,只修改email字段

17. @FieldNameConstants

生成字段名称常量:

@FieldNameConstants
public class User {
    private Long id;
    private String username;
    private String password;
}

// 使用方式
String idField = User.Fields.id; // "id"
String usernameField = User.Fields.username; // "username"

18. @UtilityClass

生成工具类:

@UtilityClass
public class StringUtils {
    public String reverse(String str) {
        return new StringBuilder(str).reverse().toString();
    }
    
    public boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }
}

Lombok的优缺点

优点

  1. 减少样板代码:自动生成getter、setter等方法,减少代码量
  2. 提高可读性:代码更加简洁,关注业务逻辑而非样板代码
  3. 减少错误:自动生成的方法不容易出错
  4. 易于维护:添加新字段时,相关方法会自动更新
  5. 支持链式调用:@Accessors(chain = true)支持链式调用
  6. 提高开发效率:减少重复编写样板代码的时间

缺点

  1. IDE支持问题:某些IDE可能需要安装插件才能正确识别Lombok生成的代码
  2. 学习成本:需要学习Lombok的注解和用法
  3. 编译时生成:代码在编译时生成,可能影响编译速度
  4. 调试困难:生成的代码不在源代码中,调试时可能不太直观
  5. 版本兼容性:不同版本的Lombok可能有兼容性问题
  6. 可能隐藏问题:自动生成的方法可能掩盖一些设计问题

最佳实践

1. 合理使用@Data

@Data虽然方便,但可能生成过多不需要的方法。建议根据实际需求使用更精确的注解:

// 不推荐
@Data
public class User {
    private Long id;
    private String username;
    private String password;
}

// 推荐
@Getter
@Setter
@ToString(exclude = "password")
@EqualsAndHashCode(of = "id")
public class User {
    private Long id;
    private String username;
    private String password;
}

2. 使用@Builder.Default设置默认值

@Builder
public class User {
    private Long id;
    private String username;
    
    @Builder.Default
    private Integer status = 1; // 默认值为1
}

3. 使用@Slf4j替代手动创建日志对象

// 不推荐
public class UserService {
    private static final Logger log = LoggerFactory.getLogger(UserService.class);
    // ...
}

// 推荐
@Slf4j
public class UserService {
    // ...
}

4. 使用@RequiredArgsConstructor进行依赖注入

// 不推荐
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    // ...
}

// 推荐
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
    // ...
}

5. 使用@Accessors控制访问器行为

@Data
@Accessors(chain = true) // 支持链式调用
public class User {
    private Long id;
    private String username;
    private String password;
}

// 使用方式
User user = new User()
    .setId(1L)
    .setUsername("zhangsan")
    .setPassword("123456");

6. 在实体类中使用Lombok

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private String username;
    
    private String password;
    
    private String email;
    
    private String phone;
    
    private Integer status;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

7. 在DTO和VO中使用Lombok

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
    private Long id;
    
    @NotBlank(message = "用户名不能为空")
    private String username;
    
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 20, message = "密码长度必须在6-20位之间")
    private String password;
    
    @Email(message = "邮箱格式不正确")
    private String email;
    
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private String phone;
}

常见问题与解决方案

1. IDE不识别Lombok生成的代码

问题:IDE无法识别Lombok生成的getter、setter等方法,导致编译错误。

解决方案

  • 安装Lombok插件
  • 启用注解处理(Enable annotation processing)
  • 重新构建项目

2. 编译错误

问题:使用Lombok后出现编译错误。

解决方案

  • 确保Lombok版本与Java版本兼容
  • 检查是否有冲突的注解
  • 清理并重新构建项目
  • 确保Lombok依赖配置正确

3. 序列化问题

问题:使用Lombok生成的类在序列化时出现问题。

解决方案

  • 使用@Getter和@Setter替代@Data
  • 手动实现序列化方法
  • 使用@JsonIgnore注解排除不需要序列化的字段

4. 继承问题

问题:使用Lombok的类在继承时出现问题。

解决方案

  • 使用@SuperBuilder代替@Builder处理继承关系
  • 在父类上使用@Getter和@Setter,在子类上使用@Data
  • 手动实现需要的方法
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class BaseEntity {
    private Long id;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class User extends BaseEntity {
    private String username;
    private String password;
    private String email;
}

5. 与JPA/Hibernate的集成问题

问题:使用Lombok的类在JPA/Hibernate中出现问题。

解决方案

  • 使用@Getter和@Setter替代@Data
  • 确保生成的equals和hashCode方法只使用实体的ID
  • 使用@ToString.Exclude排除懒加载的集合
@Getter
@Setter
@ToString(exclude = {"orders"})
@EqualsAndHashCode(of = "id")
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String username;
    
    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
    private List<Order> orders;
}

兼容性与IDE支持

Java版本兼容性

Lombok与不同Java版本的兼容性情况如下:

Lombok版本兼容的Java版本
1.18.30Java 8-21
1.18.28Java 8-20
1.18.26Java 8-19
1.18.24Java 8-18
1.18.22Java 8-17
1.18.20Java 8-16
1.18.18Java 8-15
1.18.16Java 8-14
1.18.14Java 8-13
1.18.12Java 8-12
1.18.10Java 8-11
1.18.8Java 8-10
1.18.6Java 8-9
1.18.4Java 8
1.18.2Java 8
1.18.0Java 8
1.16.22Java 8
1.16.20Java 8
1.16.18Java 8
1.16.16Java 8
1.16.14Java 8
1.16.12Java 8
1.16.10Java 8
1.16.8Java 8
1.16.6Java 8
1.16.4Java 8
1.16.2Java 8
1.16.0Java 8

注意事项

  1. 使用较新版本的Java时,建议使用较新版本的Lombok
  2. 某些Lombok功能在较新版本的Java中可能不可用或行为不同
  3. 在升级Java版本时,可能需要同时升级Lombok版本

IDE支持情况

IntelliJ IDEA

IntelliJ IDEA对Lombok的支持非常好,但需要正确配置:

  1. 插件安装

    • 打开IDE设置(File > Settings)
    • 转到插件市场(Plugins)
    • 搜索"Lombok"并安装
    • 重启IDE
  2. 注解处理

    • 打开IDE设置(File > Settings)
    • 转到构建、执行、部署 > 编译器 > 注解处理器(Build, Execution, Deployment > Compiler > Annotation Processors)
    • 勾选"启用注解处理"(Enable annotation processing)
    • 点击应用(Apply)和确定(OK)
  3. 常见问题

    • 如果IDE无法识别Lombok生成的代码,尝试重新构建项目(Build > Rebuild Project)
    • 如果出现"Lombok annotation processing does not work"错误,检查注解处理器设置
    • 如果出现"Lombok plugin is not installed"错误,安装Lombok插件
Eclipse

Eclipse对Lombok的支持需要额外安装插件:

  1. 插件安装

    • 下载Lombok安装程序(https://projectlombok.org/setup/eclipse)
    • 运行安装程序,选择Eclipse安装目录
    • 重启Eclipse
  2. 注解处理

    • 打开项目属性(右键点击项目 > Properties)
    • 转到Java编译器 > 注解处理(Java Compiler > Annotation Processing)
    • 勾选"启用项目特定设置"(Enable project specific settings)
    • 勾选"启用注解处理"(Enable annotation processing)
    • 点击应用(Apply)和确定(OK)
  3. 常见问题

    • 如果Eclipse无法识别Lombok生成的代码,尝试清理项目(Project > Clean…)
    • 如果出现"Lombok annotation processing does not work"错误,检查注解处理器设置
    • 如果出现"Lombok plugin is not installed"错误,安装Lombok插件
VS Code

VS Code对Lombok的支持需要安装扩展:

  1. 扩展安装

    • 打开扩展市场(Extensions)
    • 搜索"Lombok Annotations Support for VS Code"并安装
    • 重启VS Code
  2. Java扩展

    • 确保安装了"Extension Pack for Java"
    • 确保安装了"Language Support for Java by Red Hat"
  3. 常见问题

    • 如果VS Code无法识别Lombok生成的代码,尝试重新加载窗口(Command Palette > Developer: Reload Window)
    • 如果出现"Lombok annotation processing does not work"错误,检查Java扩展设置
NetBeans

NetBeans对Lombok的支持需要额外配置:

  1. 插件安装

    • 打开插件管理器(Tools > Plugins)
    • 搜索"Lombok"并安装
    • 重启NetBeans
  2. 注解处理

    • 打开项目属性(右键点击项目 > Properties)
    • 转到编译(Compile)
    • 勾选"启用注解处理"(Enable annotation processing)
    • 点击确定(OK)
  3. 常见问题

    • 如果NetBeans无法识别Lombok生成的代码,尝试清理并构建项目(Run > Clean and Build Project)
    • 如果出现"Lombok annotation processing does not work"错误,检查注解处理器设置

构建工具兼容性

Maven

Maven对Lombok的支持非常好,但需要正确配置:

  1. 依赖配置

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.30</version>
        <scope>provided</scope>
    </dependency>
    
  2. 注解处理器配置

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.30</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
    
  3. 常见问题

    • 如果Maven编译时出现Lombok相关错误,尝试清理项目(mvn clean)
    • 如果出现"Lombok annotation processing does not work"错误,检查注解处理器配置
Gradle

Gradle对Lombok的支持也很好,但需要正确配置:

  1. 依赖配置

    compileOnly 'org.projectlombok:lombok:1.18.30'
    annotationProcessor 'org.projectlombok:lombok:1.18.30'
    
  2. 常见问题

    • 如果Gradle编译时出现Lombok相关错误,尝试清理项目(gradle clean)
    • 如果出现"Lombok annotation processing does not work"错误,检查注解处理器配置

常见兼容性问题及解决方案

1. 编译时错误

问题:使用Lombok后出现编译错误,如"找不到符号"或"不兼容的类型"。

解决方案

  • 确保Lombok版本与Java版本兼容
  • 确保IDE已安装Lombok插件并启用了注解处理
  • 清理并重新构建项目
  • 检查是否有冲突的注解
2. 运行时错误

问题:使用Lombok生成的类在运行时出现错误,如"ClassNotFoundException"或"NoSuchMethodError"。

解决方案

  • 确保Lombok依赖配置正确
  • 确保编译时生成的代码与运行时环境兼容
  • 检查是否有版本冲突
3. 序列化问题

问题:使用Lombok生成的类在序列化时出现问题,如"NotSerializableException"。

解决方案

  • 使用@Getter和@Setter替代@Data
  • 手动实现序列化方法
  • 使用@JsonIgnore注解排除不需要序列化的字段
4. 与框架集成问题

问题:使用Lombok的类在与Spring、Hibernate等框架集成时出现问题。

解决方案

  • 使用@Getter和@Setter替代@Data
  • 确保生成的equals和hashCode方法只使用实体的ID
  • 使用@ToString.Exclude排除懒加载的集合
  • 检查框架版本与Lombok版本的兼容性
5. 与测试框架集成问题

问题:使用Lombok的类在与JUnit、Mockito等测试框架集成时出现问题。

解决方案

  • 确保测试框架版本与Lombok版本兼容
  • 使用@Getter和@Setter替代@Data
  • 手动实现需要的方法

版本升级注意事项

在升级Lombok版本时,需要注意以下几点:

  1. 检查Java版本兼容性:确保新版本的Lombok与当前使用的Java版本兼容
  2. 检查IDE插件兼容性:确保IDE的Lombok插件与新版本的Lombok兼容
  3. 检查依赖冲突:确保没有其他依赖与Lombok冲突
  4. 测试功能兼容性:测试所有使用Lombok的功能,确保升级后仍然正常工作
  5. 查看更新日志:查看Lombok的更新日志,了解新版本的变化和可能的不兼容变更

最佳实践

  1. 使用最新稳定版本:尽量使用Lombok的最新稳定版本,以获得最新的功能和bug修复
  2. 明确指定版本:在依赖配置中明确指定Lombok版本,避免使用通配符
  3. 定期更新:定期更新Lombok版本,以获得最新的功能和bug修复
  4. 测试兼容性:在更新Lombok版本后,全面测试项目的兼容性
  5. 文档化配置:将Lombok的配置和版本信息文档化,方便团队成员了解

实际应用场景

1. 实体类定义

在JPA或MyBatis-Plus等ORM框架中定义实体类:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, unique = true)
    private String username;
    
    @Column(nullable = false)
    private String password;
    
    @Column(nullable = false, unique = true)
    private String email;
    
    @Column
    private String phone;
    
    @Column(nullable = false)
    private Integer status;
    
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;
    
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;
}

2. DTO和VO定义

定义数据传输对象和视图对象:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
    private Long id;
    
    @NotBlank(message = "用户名不能为空")
    private String username;
    
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 20, message = "密码长度必须在6-20位之间")
    private String password;
    
    @Email(message = "邮箱格式不正确")
    private String email;
    
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private String phone;
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserVO {
    private Long id;
    private String username;
    private String email;
    private String phone;
    private Integer status;
    private LocalDateTime createTime;
    
    // 不包含敏感信息如密码
}

3. 服务层实现

在服务层中使用Lombok简化代码:

@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    
    public UserVO createUser(UserDTO userDTO) {
        log.info("Creating user: {}", userDTO.getUsername());
        
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(userDTO.getUsername())) {
            log.warn("Username already exists: {}", userDTO.getUsername());
            throw new BusinessException("用户名已存在");
        }
        
        // 创建用户实体
        User user = User.builder()
            .username(userDTO.getUsername())
            .password(passwordEncoder.encode(userDTO.getPassword()))
            .email(userDTO.getEmail())
            .phone(userDTO.getPhone())
            .status(1)
            .createTime(LocalDateTime.now())
            .updateTime(LocalDateTime.now())
            .build();
        
        // 保存用户
        user = userRepository.save(user);
        log.info("User created successfully: {}", user.getId());
        
        // 转换为VO并返回
        return convertToVO(user);
    }
    
    private UserVO convertToVO(User user) {
        return UserVO.builder()
            .id(user.getId())
            .username(user.getUsername())
            .email(user.getEmail())
            .phone(user.getPhone())
            .status(user.getStatus())
            .createTime(user.getCreateTime())
            .build();
    }
}

4. 控制器实现

在控制器中使用Lombok简化代码:

@Slf4j
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;
    
    @PostMapping
    public Result<UserVO> createUser(@RequestBody @Valid UserDTO userDTO) {
        log.info("收到创建用户的请求: {}", userDTO.getUsername());
        UserVO userVO = userService.createUser(userDTO);
        return Result.success(userVO);
    }
    
    @GetMapping("/{id}")
    public Result<UserVO> getUser(@PathVariable Long id) {
        log.info("收到获取用户的请求: {}", id);
        UserVO userVO = userService.getUser(id);
        return Result.success(userVO);
    }
    
    @PutMapping("/{id}")
    public Result<UserVO> updateUser(@PathVariable Long id, @RequestBody @Valid UserDTO userDTO) {
        log.info("收到更新用户的请求: {}", id);
        UserVO userVO = userService.updateUser(id, userDTO);
        return Result.success(userVO);
    }
    
    @DeleteMapping("/{id}")
    public Result<Void> deleteUser(@PathVariable Long id) {
        log.info("收到删除用户的请求: {}", id);
        userService.deleteUser(id);
        return Result.success();
    }
}

5. 异常处理

使用Lombok简化异常类的定义:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class BusinessException extends RuntimeException {
    private String code;
    private String message;
    
    public BusinessException(String message) {
        this("BUSINESS_ERROR", message);
    }
    
    public BusinessException(String code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
}

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusinessException(BusinessException e) {
        log.error("业务异常: {}", e.getMessage());
        return Result.error(e.getCode(), e.getMessage());
    }
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleValidationException(MethodArgumentNotValidException e) {
        log.error("验证异常: {}", e.getMessage());
        String message = e.getBindingResult().getFieldErrors().stream()
            .map(FieldError::getDefaultMessage)
            .collect(Collectors.joining(", "));
        return Result.error("VALIDATION_ERROR", message);
    }
    
    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        log.error("系统异常", e);
        return Result.error("SYSTEM_ERROR", "系统异常,请稍后重试");
    }
}

总结

Lombok是一个强大的Java库,可以显著减少样板代码,提高开发效率。通过合理使用Lombok的各种注解,可以使代码更加简洁、易读,同时保持代码的质量和可维护性。

在使用Lombok时,应该根据实际需求选择合适的注解,避免过度使用@Data等通用注解,以保持代码的清晰和可控。同时,需要注意Lombok的兼容性和IDE支持问题,确保开发环境的正确配置。

http://www.dtcms.com/a/113404.html

相关文章:

  • SEO长尾词优化实战技巧
  • 2025大唐杯仿真2——基站开通
  • STM32提高篇: CAN通讯
  • 【Docker】在Orin Nano上使用Docker
  • SQL ServerAlways On 可用性组配置失败
  • [ctfshow web入门] web3
  • vue2项目中,多个固定的请求域名 和 通过url动态获取到的ip域名 封装 axios
  • [leetcode]1786. 从第一个节点出发到最后一个节点的受限路径数(Dijkstra+记忆化搜索/dp)
  • 私有部署stable-diffusion-webui
  • 44. 评论日记
  • STP学习
  • 【LeetCode】大厂面试算法真题回忆(48)--静态扫描最优成本
  • 为 IDEA 设置管理员权限
  • MYSQL 存储引擎 和 日志
  • 论文阅读笔记:Denoising Diffusion Implicit Models (5)
  • 英伟达Blackwell架构深度拆解:新一代GPU如何突破算力瓶颈?
  • DHCP Snooping 主要作用
  • 【Redis】通用命令
  • 聊聊Spring AI的ChromaVectorStore
  • #SVA语法滴水穿石# (007)关于 $past 的用法
  • P10587 「ALFR Round 2」C 小 Y 的数 Solution
  • Python 如何高效实现 PDF 内容差异对比
  • 房地产之后:探寻可持续扩张的产业与 GDP 新思
  • 在线编辑数学公式
  • NDK开发:音视频处理基础
  • 解释观察者模式,如何实现观察者模式?
  • 单域名 vs 通配符:如何选择最适合你的 SSL 证书?
  • API 类别 - 方法重载
  • JVM虚拟机篇(五):深入理解Java类加载器与类加载机制
  • 纯css实现环形进度条