Lombok Configuration System – Lombok配置系统

最后修改: 2022年 1月 4日

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

1. Introduction

1.绪论

In this tutorial, we’ll talk about the configuration parameters of Lombok. We’ll go over many different options as well as how to set up our configuration correctly.

在本教程中,我们将讨论Lombok的配置参数。我们将讨论许多不同的选项,以及如何正确设置我们的配置。

2. Configuration Overview

2.配置概述

Lombok is a library that helps us eliminate almost all standard boilerplates of our Java applications. We’ll test many of the properties and configurations. The first thing is to add the Lombok dependency:

Lombok是一个帮助我们消除几乎所有Java应用程序的标准模板的库。我们将测试许多属性和配置。首先是添加Lombok依赖性。

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

The configuration system of Lombok offers us many valuable settings that frequently are the same across all the components of our project. However, it also lets us change or customize Lombok’s behavior and sometimes even defines what can or cannot be used out of all the available features. For instance, we can tell Lombok to show a warning or an error if any experimental feature is used.

Lombok的配置系统为我们提供了许多有价值的设置,这些设置通常在我们项目的所有组件中都是相同的。然而,它也让我们改变或定制Lombok的行为,有时甚至定义了所有可用功能中哪些可以使用,哪些不可以使用。例如,我们可以告诉Lombok在使用任何实验性功能时显示警告或错误。

To start defining or customizing Lombok’s behavior, we have to create a file called lombok.config. This file can leave at the root of our project, source code, or any package. Once created, all the source files in the child directories will inherit the configs defined in such a file. It’s possible to have multiple config files. For example, we can define a config file in our root directory with general properties and create another one in a given package defining other properties.

为了开始定义或定制Lombok的行为,我们必须创建一个名为lombok.config.的文件。这个文件可以留在我们的项目、源代码或任何包的根目录下。一旦创建,子目录中的所有源文件将继承这样一个文件中定义的配置。有可能有多个配置文件。例如,我们可以在我们的根目录中定义一个具有一般属性的配置文件,并在一个给定的包中创建另一个定义其他属性的文件。

The new configs will influence all classes of the given package and all children packages. Also, in the case of multiple definitions of the same property, the one closer to the class or member takes precedence.

新的配置将影响给定包的所有类和所有子包。另外,在同一属性有多个定义的情况下,离类或成员更近的那个定义优先考虑。

3. Basic Configurations

3.基本配置

One of the first things to mention is too many feature properties to discuss. For this reason, we’ll see only the most common ones. To check the available options, let’s go to Lombok’s page, download the jar, and run the following command in the terminal:

首先要提到的一件事是有太多的特征属性需要讨论。出于这个原因,我们将只看到最常见的那些。为了检查可用的选项,让我们到Lombok的页面,下载jar,并在终端运行以下命令。

java -jar lombok.jar config -g --verbose

As a result, we’ll see a complete list of all properties and their possible values and a short description explaining its goal.

结果是,我们会看到一个所有属性及其可能值的完整列表,以及解释其目标的简短描述。

Now, let’s see a typical lombok.config file:

现在,让我们看看一个典型的lombok.config文件。

config.stopBubbling = true
lombok.anyconstructor.addconstructorproperties = false
lombok.addLombokGeneratedAnnotation = true
lombok.experimental.flagUsage = WARNING

# ... more properties

The properties used in the file are for illustration purposes only. We’ll discuss them later. But here, we can observe the format of the Lombok properties and their definition.

文件中使用的属性只是为了说明问题。我们将在后面讨论它们。但在这里,我们可以观察Lombok属性的格式和它们的定义。

Let’s begin with the config.stopBubbling property – this option tells the configuration system not to search for config files in the parent directories. It’s a good practice to add this property to the root of your workspace or project. By default, its value is false.

让我们从config.stopBubbling属性开始 – 这个选项告诉配置系统不要在父目录下搜索配置文件。把这个属性添加到你的工作区或项目的根部是一个好的做法。默认情况下,其值为false

4. Main Properties

4.主要属性

4.1. Global Config Keys

4.1.全局配置键

Global config keys are configurations that may affect many of the configuration systems themselves. Next, we’ll see some examples of such keys.

全球配置键是可能影响许多配置系统本身的配置。接下来,我们将看到这种键的一些例子。

The first key we’ll discuss is lombok.anyConstructor.addConstructorProperties. It adds the @java.beans.ConstructorProperties annotation to all constructors with arguments. Usually, frameworks that use reflection on constructors need this annotation to map properties and know the correct order of the params in the constructor. Here is the code in the Lombok version:

我们要讨论的第一个键是 lombok.anyConstructor.addConstructorProperties。它将@java.beans.ConstructorProperties注解添加到所有带参数的构造函数中。通常,在构造函数上使用反射的框架需要这个注解来映射属性并知道构造函数中参数的正确顺序。下面是Lombok版本的代码。

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class Account {
    private double balance;
    private String accountHolder;
}

And here is the generated code:

下面是生成的代码。

public class Account {
    private double balance;
    private String accountHolder;

    @ConstructorProperties({"balance", "accountHolder"})
    @Generated
    public Account(double balance, String accountHolder) {
        this.balance = balance;
        this.accountHolder = accountHolder;
    }
 
    @Generated
    public Account() {}

    // default generated getter and setters
}

In the code snippet above, we can see the generated class that contains the @ConstructorProperties annotation.

在上面的代码片段中,我们可以看到生成的类包含@ConstructorProperties注解。

Next, we have the lombok.addLombokGeneratedAnnotation. If true, Lombok will mark all generated methods with the @lombok.Generated. That comes in handy when removing Lombok-generated methods from package scanning or code coverage tools.

接下来,我们有 lombok.addLombokGeneratedAnnotation. 如果true,Lombok将用@lombok.Generated.标记所有生成的方法。这在从包扫描或代码覆盖工具中移除Lombok生成的方法时很方便

Another helpful key is lombok.addNullAnnotations. This property supports many built-in options such as javax (JSR305), eclipse, JetBrains, NetBeans, Android, and more. It’s also possible to use annotations defined by ourselves, like CUSTOM:com.example.NonNull:example.Nullable. Lombok will add the nullable or NotNull annotations whenever it makes sense.

另一个有用的键是 lombok.addNullAnnotations。这个属性支持许多内置选项,比如javax(JSR305)、eclipse、JetBrains、NetBeans、Android等等。也可以使用我们自己定义的注释,比如CUSTOM:com.example.NonNull:example.Nullable。Lombok会在有意义的时候添加nullableNotNull注解。

Lastly, we have the lombok.addSuppressWarnings, that if false, Lombok stops adding the annotation @SuppressWarnings(“all”), which is the current default behavior. That is useful if we use static analyzers on the generated code.

最后,我们有 lombok.addSuppressWarnings,如果false,Lombok会停止添加注解@SuppressWarnings(“all”),这是当前的默认行为。如果我们在生成的代码上使用静态分析器,这就很有用。

4.2. Other Config Keys

4.2.其他配置键

Being the first feature-specific key lombok.accessors.chain, if true, changes the behavior of the setter methods. Instead of void return, those methods will return this. Allowing the chaining of the calls, as shown below:

作为第一个特定功能的键 lombok.accessors.chain,如果true,改变setter方法的行为。而不是void return这些方法将返回this。允许连锁调用,如下图所示。

@Test
void should_initialize_account() {
    Account myAccount = new Account()
      .setBalance(2000.00)
      .setAccountHolder("John Snow");

    assertEquals(2000.00, myAccount.getBalance());
    assertEquals("John Snow", myAccount.getAccountHolder());
}

Similar to the previous one, the lombok.accessors.fluent makes Lombok remove the prefix set and get from the accessors methods using only the property names to name them.

与前一个类似, lombok.accessors.fluent使Lombok从accessors方法中移除前缀setget,只使用属性名来命名它们。

The lombok.log.fieldName key changes the name of the generated log field when configured by the user. By default, the lombok.log.fieldName key uses log to name the field, but in our example, we changed it to domainLog:

lombok.log.fieldName键在用户配置时改变生成的日志字段的名称。默认情况下,lombok.log.fieldName键使用log来命名该字段,但在我们的例子中,我们把它改为domainLog

#Log name customization
lombok.log.fieldName = domainLog

We can then see it in action:

然后我们就可以看到它在行动。

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Log
public class Account {

    // same as defined previously

   public Account withdraw(double amount) {
        if (this.balance - abs(amount) < 0) {
            domainLog.log(Level.INFO, "Transaction denied for account holder: %s", this.accountHolder);
            throw new IllegalArgumentException(String.format("Not enough balance, you have %.2f", this.balance));
        }

        this.balance -= abs(amount);
        return this;
    }
}

The next is lombok.(featureName).flagUsage. This set of properties has warning, error, and allow as possible values. We can use them to control which Lombok features are permitted in our projects. For example, it is possible to use the word experimental and the value warning to output a message in the log if any experimental feature is used:

接下来是 lombok.(featureName).flagUsage。这组属性有warning, error,allow作为可能的值。我们可以用它们来控制我们的项目中允许哪些Lombok功能。例如,可以使用单词experimental和值warning,在使用任何实验性功能时在日志中输出一条信息。

/home/dev/repository/git/tutorials/lombok/src/main/java/com/baeldung/lombok/configexamples/TransactionLog.java:9:
 warning: Use of any lombok.experimental feature is flagged according to lombok configuration.
@Accessors(prefix = {"op"})

4.3. Special Config Keys

4.3.特殊配置键

Some keys are not common key-values properties, like lombok.copyableAnnotations. That property is different because it represents a list of fully qualified annotation types. When added to a field, Lombok will copy those annotations to constructors, getters, and setters related to the field. A typical use case for this feature is bean definitions with Spring, where the annotation @Qualifier and @Value frequently have to be copied to the constructor arguments. Other frameworks also leverage this feature.

有些键不是常见的键值属性,比如 lombok.copyableAnnotations。该属性是不同的,因为它代表一个完全合格的注释类型的列表。当添加到一个字段时,Lombok将把这些注解复制到与该字段相关的构造器、获取器和设置器。该功能的典型用例是Spring的Bean定义,其中注释@Qualifier@Value经常需要被复制到构造器参数中。其他框架也利用了这一特性。

To add annotations to the list, the user must use the following expression: lombok.copyableAnnotations += com.test.MyAnnotation. The library uses the mechanism to propagate the nullable annotation mentioned before:

要将注释添加到列表中,用户必须使用以下表达式。lombok.copyableAnnotations += com.test.MyAnnotation。该库使用之前提到的机制来传播nullable注解。

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Log
public class Account {

    @NonNull
    private Double balance = 0.;
    @NonNull
    private String accountHolder = "";

    // other methods
}

Now, the code generated by Lombok:

现在,由Lombok生成的代码。

public class Account {

    @Generated
    private static final Logger domainLog = Logger.getLogger(Account.class.getName());
    @NonNull
    private Double balance = 0.0D;
    @NonNull
    private String accountHolder = "";

    @ConstructorProperties({"balance", "accountHolder"})
    @Generated
    public Account(@NonNull Double balance, @NonNull String accountHolder) {
        if (balance == null) {
            throw new NullPointerException("balance is marked non-null but is null");
        } else if (accountHolder == null) {
            throw new NullPointerException("accountHolder is marked non-null but is null");
        } else {
            this.balance = balance;
            this.accountHolder = accountHolder;
        }
    }

    @NonNull
    @Generated
    public Double getBalance() {
        return this.balance;
    }

    @NonNull
    @Generated
    public String getAccountHolder() {
        return this.accountHolder;
    }

    // Rest of the class members...

}

And finally, we have a clear lombok.(anyConfigKey) directive. It restores any configuration key to its default value. If someone changed the value of the given key in any parent config file, it would now be ignored. We can use the directive clear, followed by any Lombok config key:

最后,我们有一个 clear lombok.(anyConfigKey) 指令。 它将任何配置键恢复到其默认值。如果有人在任何父级配置文件中改变了给定的键的值,现在它将被忽略。我们可以使用指令clear,后面跟着任何Lombok配置键。

clear lombok.addNullAnnotations

4.4. File Directives

4.4.文件指令

Now, we have a good idea of how Lombok’s configuration system works and some of its features. Of course, this was not an extensive list of all available features, but from here, we must have a clear understanding of how to use it. Last but not least, let’s see how to import configurations defined in another file inside our current configuration file.

现在,我们对Lombok的配置系统如何工作以及它的一些功能有了一个很好的了解。当然,这不是所有可用功能的广泛列表,但从这里开始,我们必须对如何使用它有一个清晰的认识。最后但并非最不重要的是,让我们看看如何在我们当前的配置文件中导入另一个文件中定义的配置。

For importing a config file inside another, the directives have to go on top of the file, and the path can be either relative or absolute:

对于将一个配置文件导入另一个文件,指令必须放在文件的顶部,路径可以是相对的,也可以是绝对的

##     relative or absolute path  
import lombok_feature.config

config.stopBubbling = true
lombok.anyconstructor.addconstructorproperties=false
lombok.addLombokGeneratedAnnotation = true
lombok.addSuppressWarnings = false

Just to illustrate, the imported file:

只是为了说明,导入的文件。

# lombok_feature.config file

lombok.experimental.flagUsage = warning

5. Conclusion

5.总结

In this article, we looked at the configuration system from Lombok, its different properties, and how they affect its functioning. Although, as mentioned before, there are many more options available, we only looked at the most common ones. Feel free to check more on the Lombok page.

在这篇文章中,我们看了龙目岛的配置系统,它的不同属性,以及它们如何影响其功能。尽管如前所述,还有许多可用的选项,但我们只看了最常见的选项。请随时在Lombok页面上查看更多内容。

As usual, all code samples used in this article are available over on GitHub.

像往常一样,本文中使用的所有代码样本都可以在GitHub上找到