Lombok Builder with Custom Setter – 带有自定义设定器的龙目建设者

最后修改: 2018年 10月 31日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

Project Lombok is a popular Java library to help reduce the amount of boilerplate code a developer needs to write.

Project Lombok是一个流行的Java库,可以帮助减少开发人员需要编写的模板代码的数量。

In this tutorial, we’ll take a look at how Lombok’s @Builder annotation works and how we can customize it for our specific needs.

在本教程中,我们将看看Lombok的@Builder注释是如何工作的,以及我们如何为我们的特定需求定制它。

2. Maven Dependency

2.Maven的依赖性

Let’s start by adding the dependency to our pom.xml:

让我们先把依赖性添加到我们的pom.xml

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>

3. Lombok Builder Annotation

3.龙卷风Builder注释

Before we look into customizing Lombok’s generated builder class, let’s do a quick recap of how the Lombok @Builder annotation works. We already have a full introduction into Lombok’s features.

在我们研究定制Lombok生成的构建器类之前,让我们快速回顾一下Lombok @Builder注解是如何工作的。我们已经有一个完整的介绍Lombok的功能。

The @Builder annotation can be used to automatically generate a builder for our class. For our example, we’ll use a messaging system where one user can send a message to another user. The message is either a simple text string or a File. Using Lombok, we can define our Message class as follows:

@Builder注解可以用来为我们的类自动生成一个构建器。在我们的例子中,我们将使用一个消息传递系统,一个用户可以向另一个用户发送一条消息。该消息是一个简单的文本字符串或一个文件。使用Lombok,我们可以定义我们的Message类,如下所示。

@Builder
@Data
public class Message {
    private String sender;
    private String recipient;
    private String text;
    private File file;
}

@Data generates all the boilerplate that is normally associated with a simple POJO (Plain Old Java Object): getters for all fields, setters for all non-final fields, and appropriate toString, equals and hashCode implementations, and a constructor.

@Data生成所有通常与简单POJO(Plain Old Java Object)相关的模板:所有字段的getters,所有非最终字段的setters,以及适当的toStringequalshashCode实现,和一个构造器。

Using the generated builder, we can now generate instances of our Message class:

使用生成的构建器,我们现在可以生成我们的Message类的实例。

Message message = Message.builder()
  .sender("user@somedomain.com")
  .recipient("someuser@otherdomain.com")
  .text("How are you today?")
  .build();

The @Builder annotation also supports default values for attributes but we won’t go into that now. It should be clear from this example that the @Builder annotation is quite powerful and can replace a lot of boilerplate code.

@Builder 注解还支持属性的默认值,但我们现在不会去讨论这个问题。从这个例子中应该可以看出,@Builder 注解是相当强大的,可以取代很多模板代码。

4. Customizing Lombok Builders

4.定制Lombok建设者

The previous section showed how we can use Lombok to generate a builder class. But there may be cases where the generated builder is not enough. In our example, we have a constraint that the message can only contain either text or a file. It cannot have both. Lombok doesn’t know that of course and the generated builder will happily allow us to get into that illegal state.

上一节展示了我们如何使用Lombok来生成一个构建器类。但是可能有一些情况下,生成的构建器是不够的。在我们的例子中,我们有一个约束条件,即消息只能包含文本或文件。它不能同时包含两者。Lombok当然不知道这一点,而且生成的构建器会很乐意让我们进入这种非法状态。

Luckily we can address this problem customizing the builder.

幸运的是,我们可以通过定制构建器来解决这个问题。

Customizing a Lombok builder is simple and straightforward: we write the parts of the builder that we want to customize and the Lombok @Builder annotation will simply not generate those parts. So in our example, that would be:

定制一个Lombok构建器是简单而直接的。我们写下我们想要定制的构建器的部分,Lombok @Builder 注解将简单地不生成这些部分。所以在我们的例子中,这将是。

public static class MessageBuilder {
    private String text;
    private File file;

    public MessageBuilder text(String text) {
        this.text = text;
        verifyTextOrFile();
        return this;
    }

    public MessageBuilder file(File file) {
        this.file = file;
        verifyTextOrFile();
        return this;
    }

    private void verifyTextOrFile() {
        if (text != null && file != null) {
            throw new IllegalStateException("Cannot send 'text' and 'file'.");
        }
    }
}

Please note that we did not have to declare the sender and recipient members, or the builder methods associated with them. Lombok will still generate those for us.

请注意,我们不需要声明senderrecipient成员,或者与之相关的构建器方法。Lombok仍将为我们生成这些。

If we try to generate a Message instance with both text and a file with the following code:

如果我们试图用以下代码生成一个既有文本又有文件的Message实例。

Message message = Message.builder()
  .sender("user@somedomain.com")
  .recipient("someuser@otherdomain.com")
  .text("How are you today?")
  .file(new File("/path/to/file"))
  .build();

It will result in the following exception:

这将导致以下异常。

Exception in thread "main" java.lang.IllegalStateException: Cannot send 'text' and 'file'.

5. Conclusion

5.结论

In this quick article, we looked at how to customize the Lombok builder.

在这篇快速文章中,我们看了如何定制Lombok builder。

As always, the code is available over on GitHub.

像往常一样,代码可在GitHub上获得