Spring注解之构建器@Builder的用法

简述

Builder使用创建者模式又叫建造者模式。简单来说,就是一步步创建一个对象,它对用户屏蔽了里面构建的细节,但却可以精细地控制对象的构造过程。

基础使用

@Builder 注解为你的类生成相对略微复杂的构建器API。
@Builder 可以让你以下面显示的那样调用你的代码,来初始化你的实例对象:

Student.builder().sno("001").sname("admin").sage(18).sphone("110").build();

使用场景

遇到多个构造器参数时可以考虑使用构建器

如果已知将来可能需要添加很多的参数,通常一开始就使用构建器。

重叠构造器

平时都习惯使用重叠构造器(telescoping constructor)模式,在这种模式下,提供的第一个构造器只有必要的参数,第二个构造器有一个可选参数,第三个构造器有两个可选参数,依次类推,最后一个构造器包含所有可选的参数。
下面有个示例:

@Data
public class Person {

    private String name;         // 必填属性
    private String age;          // 选填属性
    private String sex;          // 选填属性
    private String country;      // 选填属性

    public Person(String name) {
        this(name, null);
    }

    public Person(String name, String age) {
        this(name, age, null);
    }

    public Person(String name, String age, String sex) {
        this(name, age, sex, null);
    }

    public Person(String name, String age, String sex, String country) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.country = country;
    }
}

当创建实例时,可以根据实际参数情况,选择使用具体的构造器,如下所示。

Person person = new Person("张三");
Person person1 = new Person("李四", "12");

JavaBeans模式

遇到许多可选的构造器参数的时候,还有第二种替代方法,即 JavaBeans 模式,在这种模式下,先调用一个无参构造器来创建对象,然后再调用 setter 方法来设置每个必要的参数,以及每个相关的可选参数。

创建实例如下:

Person person = new Person();
person.setName("张三");
person.setAge("23");
person.setSex("男");

建造者(Builder)模式

建造者模式既能保证像重叠构造器模式那样的安全性,也能保证像 Java Beans 模式那么好的可读性。

它不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,得到一个 builder 对象。然后客户端在 builder 对象上调用类似于 setter 的方法,来设置每个相关的可选参数。最后,客户端调用无参的 build 方法来生成通常是不可变的对象。这个 builder 通常是它构建的静态成员类。

建造者模式代码示例:使用@Builder注解即可

@Builder
public class User {

    // 设置初始值
    @Builder.Default
    private final Integer id = UUID.randomUUID().toString();
    private final Integer code = 200;
    private String username;
    private String password;

    // value 修改添加集合元素的方法名
    @Singular(value = "hobby")
    private List<String> hobbies;

    @Builder.Default
    private long insertTime = System.currentTimeMillis();
}

创建实例如下:

User user = User.Builder().username("admin").password("123456").hobby("张三").hobby("李四").build();

1、@Builder.Default 的使用
当我在使用这个实体对象时,我就不需要在为这两个字段进行初始化值
当然,你如果再对这两个字段进行设值的话,那么默认定义的值将会被覆盖掉

2、@Singular 关于集合操作的三个方法:
hobby(String hobby) :向集合中添加一个元素
hobbies(Collection<? extends String> hobbies) :添加一个集合所有的元素
clearHobbies() :清空当前集合数据

3、@Builder(toBuilder=true)
默认false,为 ture 时可以修改这个对象属性值
示例:
// 创建一个新的对象user2,原来的对象属性是不可变的,并修改了密码,且list在原来基础上新增一个"老六"
User user2 = user.toBuilder().hobby("老六").password("888").build();

如果想改变原来对象的属性,还可以给这个实体类再添加上 @Data 或者 @setter 方法。

@Builder内部帮我们做了什么?

1、创建一个名为 ThisClassBuilder 的内部静态类,并具有和实体类形同的属性(称为构建器)。
2、在构建器中:对于目标类中的所有的属性和未初始化的 final 字段,都会在构建器中创建对应属性。
3、在构建器中:创建一个无参的 default 构造函数。
4、在构建器中:对于实体类中的每个参数,都会对应创建类似于 setter 的方法,只不过方法名与该参数名相同。 并且返回值是构建器本身(便于链式调用),如上例所示。
5、在构建器中:一个 build() 方法,调用此方法,就会根据设置的值进行创建实体对象。
6、在构建器中:同时也会生成一个 toString() 方法。
7、在实体类中:会创建一个 builder() 方法,它的目的是用来创建构建器。

@Builder 全局配置

# 是否禁止使用@Builder
lombok.builder.flagUsage = [warning | error] (default: not set)
# 是否使用Guaua
lombok.singular.useGuava = [true | false] (default: false)
# 是否自动使用singular,默认是使用
lombok.singular.auto = [true | false] (default: true)

使用总结

Builder 模式模拟了具名的可选参数。与构造器相比,builder 的略微优势在于,它可以有多个可变参数,因为 builder 是利用单独的方法来设置每一个参数。

Builder 模式也有它自身的不足。为了创建对象,必须先创建它的构建器。
Builder 模式还比重叠构造器模式更加冗长,因此它只有在很多参数的时候才使用。

简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder 模式就是一种不错的选择,特别是当大多数参数都是可选或者类型相同的时候。

与使用重叠构造器模式相比,使用 Builder 模式的客户端代码将更易于阅读和编写,构建器也比 Java Beans 更加安全。

posted @ 2022-09-22 16:58  盗梦笔记  阅读(3008)  评论(0编辑  收藏  举报