楼主: 22657_web
45 0

@Builder注解完全详解(Lombok 核心注解) [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-12-11
最后登录
2018-12-11

楼主
22657_web 发表于 2025-11-21 10:21:04 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

注解完全详解(Lombok 核心注解)

@Builder

Lombok 工具提供的核心注解,用于自动生成「建造者模式」代码,简化对象创建逻辑,提升代码的可读性与维护性。它并非 Spring 框架中的注解,而是与

@Data
@Getter
等同属于 Lombok 生态体系的一部分,专注于减少样板代码。

一、核心基础

1. 归属与依赖

所属工具:Lombok(一款在编译期生成代码的辅助工具)

注解全类名:

lombok.Builder
(注意:该注解不属于 Spring 包路径,Spring 的注解通常位于
org.springframework
下)

依赖要求:使用前必须在项目中引入 Lombok 的依赖配置(Maven 或 Gradle),否则注解将不会生效:

<!-- Maven 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 建议使用稳定版本 -->
<scope>provided</scope> <!-- 仅在编译阶段有效,不打包进最终 Jar 文件 -->
</dependency>

IDE 支持:需要在 IDEA 或 Eclipse 中安装 Lombok 插件,否则编辑器可能报红或提示语法错误,但不影响实际编译运行。

2. 核心作用

@Builder 注解会自动为类生成实现「建造者模式」所需的一系列结构,包括:

  • 一个名为 XXXBuilder 的静态内部类(如
    XXXBuilder
    所示,例如
    UserBuilder
    );
  • 在 Builder 类中为每个属性生成链式 setter 方法(如
    username(String username)
    );
  • 在实体类中添加静态的 builder() 方法(即
    builder()
    ),用于获取 Builder 实例;
  • Builder 类中提供 build() 方法(对应
    build()
    ),用于最终构建并返回实体对象。

简而言之:通过链式调用方式替代传统繁琐的构造函数或逐个 set 属性的方式,使对象创建更清晰、灵活。

二、基本用法

1. 单个类上的直接应用

只需在目标实体类上添加 @Builder 注解即可启用建造者模式功能:

import lombok.Builder;
import lombok.Data;

// 结合 @Data 自动生成 getter/setter/toString 等方法
@Data
@Builder
public class User {
    private String username; // 用户名(必填)
    private Integer age;     // 年龄(可选)
    private String address;  // 地址(可选)
    private String email;    // 邮箱(可选)
}
@Builder

2. 创建对象示例

无需手动编写任何 Builder 相关代码,直接利用链式语法创建实例:

// 使用建造者模式构建对象(支持任意属性顺序)
User user = User.builder()
    .username("zhangsan") // 必填项
    .age(25)              // 可选项(按需设置)
    .address("北京市朝阳区")
    .email("zhangsan@xxx.com")
    .build(); // 最终生成 User 对象

// 输出结果:User(username=zhangsan, age=25, address=北京市朝阳区, email=zhangsan@xxx.com)
System.out.println(user);

3. 与传统方式对比

方式 代码示例 优点 缺点
构造方法
new User("zhangsan", 25, "北京", "xxx@xxx.com")
写法简洁 参数顺序固定,易错;可选参数需大量重载
setter 方法
User u = new User(); u.setUsername("zhangsan"); u.setAge(25); ...
设置顺序自由 代码冗长,容易遗漏字段赋值
建造者模式
@Builder
User.builder().username("zhangsan").age(25).build()
支持链式调用、顺序自由、语义清晰、可读性强 需引入 Lombok 依赖

三、高级特性

1. 为属性设置默认值

若希望某些可选字段具有默认值,可在定义属性时直接赋予初始值:

@Data
@Builder
public class User {
    private String username;
    private Integer age = 18;           // 默认年龄设为 18
    private String address = "未知地址"; // 默认地址
    private String email;
}

在使用 builder 构建对象时,未显式设置的属性将自动采用默认值:

User user = User.builder()
    .username("lisi")
    .email("lisi@xxx.com")
    .build();

// 输出:User(username=lisi, age=18, address=未知地址, email=lisi@xxx.com)
System.out.println(user);

2. 必选属性强制校验

@Builder 注解本身并不提供对“必填字段”的强制检查机制。如需实现此类校验逻辑,可通过以下方式补充:

@Builder

3. 与其他 Lombok 注解的组合使用

在实际开发中,@Builder 常与多个 Lombok 注解结合使用,以满足更广泛的使用场景。常见的组合如下:

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Data           // 自动生成 getter、setter、toString、equals 和 hashCode 方法
@Builder        // 启用建造者模式,支持链式调用创建对象
@NoArgsConstructor // 生成无参构造函数(便于 Spring 反射或 JSON 反序列化)
@AllArgsConstructor // 生成全参构造函数(Builder 内部依赖此构造函数)
public class User {
    private String username;
    private Integer age;
    private String address;
}

组合使用说明:

@NoArgsConstructor

添加 @NoArgsConstructor 可解决 Spring 容器注入或 JSON 反序列化过程中因缺少无参构造函数而导致的问题;

@AllArgsConstructor

@AllArgsConstructor@Builder 底层实现所依赖的关键注解。虽然 Lombok 在使用 @Builder 时会自动补全全参构造函数,但显式声明更为安全,可避免潜在的注解冲突或行为不一致。

@Builder

4. 控制部分属性不参与建造者构建

若某些字段不应由外部通过 Builder 设置(例如数据库自增的 ID),可通过设置访问级别限制来实现。推荐方式是使用 @Setter(AccessLevel.NONE),从而优雅地排除特定字段:

import lombok.Builder;
import lombok.Data;
import lombok.Setter;
import lombok.AccessLevel;

@Data
@Builder
public class User {
    private String username;
    private Integer age;
    @Setter(AccessLevel.NONE) // 禁止生成 setter 方法,且不加入 Builder 构建流程
    private Long id; // 自增主键,由数据库维护,禁止手动赋值
}

此时尝试通过 Builder 设置 id 将导致编译错误:

User user = User.builder()
    .username("wangwu")
    .age(30)
    // .id(1001) // 编译失败:Builder 中不存在该方法
    .build();
id

5. 自定义静态建造者入口方法名称

默认情况下,获取 Builder 实例的方法名为 builder(),但可通过 builderMethodName 属性进行自定义命名,提升语义清晰度:

@Data
@Builder(builderMethodName = "create") // 将建造者入口方法改为 create()
public class User {
    private String username;
    private Integer age;
}

调用时使用新定义的方法名启动构建流程:

User user = User.create() // 替代原有的 User.builder()
    .username("zhaoliu")
    .age(28)
    .build();
XXX.builder()
@Builder(builderMethodName = "create")

四、常见问题与避坑指南

1. 是否与 @ConfigurationProperties 存在冲突?

不存在冲突。@ConfigurationProperties 是 Spring Boot 提供的用于绑定配置文件属性的注解,运行时由 Spring 处理;而 @Builder 是 Lombok 在编译期生成代码的工具,两者作用阶段不同,互不影响,可以共存:

import lombok.Builder;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "user")
@Data
@Builder
public class User {
    private String username;
    private Integer age;
    private String address;
}
@ConfigurationProperties
@Builder

注解配合实现非空校验:通过 @NonNull 强制要求必须设置某些关键属性,否则在运行时抛出空指针异常:

import lombok.Builder;
import lombok.Data;
import lombok.NonNull;

@Data
@Builder
public class User {
    @NonNull // 必须传入 username,否则运行时报错
    private String username;
    private Integer age;
    private String address;
}

错误示例(未设置必填项):

// 编译通过,但运行时抛出异常:java.lang.NullPointerException: username is marked non-null but is null
User user = User.builder().age(20).build();
@NonNull
NullPointerException
username

局部属性排除方案补充:除 @Setter(AccessLevel.NONE) 外,也可使用 @Builder.Exclude 显式指定某字段不参与构建过程,但目前支持有限且需注意版本兼容性,因此更推荐上述 setter 控制方式。

@Builder.Default
transient
@Setter(AccessLevel.NONE)
@ConfigurationProperties(prefix = "sky.jwt")
@Data
@Builder
public class JwtProperties {
    private String adminSecretKey;
    private long adminTtl;
    private String adminTokenName;
}

在使用 Lombok 的建造者模式时,若实体类存在继承关系,直接使用 @Builder 注解会导致父类的属性无法被 Builder 设置。此时应采用 @SuperBuilder 注解,该功能自 Lombok 1.18.16 版本起支持。

@Builder

首先,父类需标注 @SuperBuilder:

import lombok.Data;
import lombok.SuperBuilder;

@Data
@SuperBuilder
public class BaseEntity {
    private Long id;
    private String createTime;
}

子类同样使用 @SuperBuilder,可自动继承父类的所有属性:

@Data
@SuperBuilder
public class User extends BaseEntity {
    private String username;
    private Integer age;
}

构建对象时,可通过 superBuilder() 方法链式设置包括父类在内的全部属性:

User user = User.superBuilder()
    .id(1001)
    .createTime("2025-11-18")
    .username("zhangsan")
    .age(25)
    .build();
@SuperBuilder

当实体类包含集合类型字段时,若直接初始化赋值,例如:

private List<String> tags = new ArrayList<>();

会导致所有实例共享同一个集合引用,引发“静态共享”问题。正确做法是使用 @Builder.Default 注解,确保每个对象拥有独立的集合实例。

@Builder.Default

示例如下:

import lombok.Builder;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;

@Data
@Builder
public class User {
    private String username;

    // 错误方式:所有对象共享同一 list 实例
    // private List<String> tags = new ArrayList<>();

    // 正确方式:每个对象创建独立 list
    @Builder.Default
    private List<String> tags = new ArrayList<>();
}

若编译过程中出现“找不到符号:方法 builder()”错误,可能由以下原因导致:

  • 原因一:项目未引入 Lombok 依赖,或当前版本过低不支持相关特性;
  • 原因二:开发环境中(如 IDEA)未安装 Lombok 插件,导致编辑器无法识别生成的方法,尽管实际编译可通过;
  • 原因三:类中手动定义了与 Builder 冲突的方法,例如已存在名为 builder() 的静态工厂方法或其他构造逻辑。
builder()

适用场景与不适用场景

适用场景:

  • 实体类属性较多,尤其存在大量可选字段时,Builder 模式能显著提升对象构建的清晰度和灵活性;
  • 追求代码可读性,希望明确展示每个属性的赋值过程;
  • 项目中已集成 Lombok(如配合 @Data、@AllArgsConstructor 等注解使用),无需额外引入新工具库。
@Data

不适用场景:

  • 简单 POJO 类(仅包含 2-3 个属性),此时直接调用构造函数或 setter 更加直观简洁;
  • 需要创建不可变对象(immutable object),建议结合 final 关键字与 @Singular 或手动实现 Builder,而非依赖默认 @Builder 行为;
final
@AllArgsConstructor

@Builder 是 Lombok 提供的核心注解,并非 Spring 框架的一部分,其主要作用是自动生成符合建造者模式的构建代码。

@Builder

其核心优势包括:

  • 支持链式调用,语法流畅;
  • 属性设置顺序自由,无需遵循参数列表顺序;
  • 减少模板代码,提升可读性和维护性。

常见高效组合为:@Data + @Builder,适用于绝大多数复杂实体类的构建需求。

@Data + @Builder + @NoArgsConstructor + @AllArgsConstructor

使用过程中需注意避坑要点:

  • 集合类型的默认值必须配合 @Builder.Default 使用,避免实例间状态污染;
  • 涉及继承结构时,应使用 @SuperBuilder 而非 @Builder;
  • @Builder 与 Spring 相关注解(如 @ConfigurationProperties、@Component)完全兼容,无冲突风险。
@Builder.Default
@SuperBuilder
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:builder Build MBO der Properties

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-5 18:21