Spring Boot 配置元數據指南

  • 2019 年 10 月 24 日
  • 筆記

1. 概覽

在編寫 Spring Boot 應用程序時,將配置屬性映射到 Java bean 上是非常有用的。但是,記錄這些屬性的最好方法是什麼呢?

在本教程中,我們將探討 Spring Boot Configuration Processor關聯的 JSON 元數據文件,該 JSON 文檔記錄每個屬性的含義、約束等。

2. 配置元數據

作為開發人員,我們開發的大多數應用程序在某種程度上必須是可配置的。但是在通常情況下,我們並不能夠真正的理解配置參數的作用,比如它有默認值,又或者是過時的,有時我們甚至不知道該屬性的存在。

為了幫助我們理清楚,Spring Boot 生成了配置元數據的 JSON 文件,為我們提供關於如何使用屬性的有用信息。所以,配置元數據是一個描述性文件,它包含與配置屬性交互所需的必要信息。

這個文件的好處是 IDE 也能讀懂它,從而為我們提供自動完成 Spring 屬性配置的工作,以及其他配置提示。

3. 依賴

為了生成此配置元數據,我們將使用 spring-boot-configuration-processor 的依賴.

因此,讓我們繼續將依賴項添加為可選依賴

<dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-configuration-processor</artifactId>      <version>2.1.7.RELEASE</version>      <optional>true</optional>  </dependency>

這種依賴關係將為我們提供在構建項目時調用的 Java 註解處理器。我們稍後會詳細討論這個問題。

為了防止 @ConfigurationProperties 不應用於我們的項目使用的其他模塊,在 Maven 中添加依賴項為可選依賴 是最好的做法。

4. 配置屬性示例

現在來研究處理器是怎麼工作的,我們需要使用 Java bean 獲取在 Spring Boot 應用程序中包含一些屬性:

@Configuration  @ConfigurationProperties(prefix = "database")  public class DatabaseProperties {        public static class Server {          private String ip;          private int port;            // standard getters and setters      }        private String username;      private String password;      private Server server;        // standard getters and setters  }

要做到這一點,我們可以使用 @ConfigurationProperties 註解。配置處理器會掃描使用了此註解的類和方法,用來訪問配置參數並生成配置元數據。

讓我們將這些屬性中添加到屬性文件中。在示例中,我們把文件命名為 databaseproperties-test.properties

#Simple Properties  database.username=baeldung  database.password=password

我們還將添加一個測試,以確保我們都做對了:

@RunWith(SpringRunner.class)  @SpringBootTest(classes = AnnotationProcessorApplication.class)  @TestPropertySource("classpath:databaseproperties-test.properties")  public class DatabasePropertiesIntegrationTest {        @Autowired      private DatabaseProperties databaseProperties;        @Test      public void whenSimplePropertyQueriedThenReturnsPropertyValue()        throws Exception {          Assert.assertEquals("Incorrectly bound Username property",            "baeldung", databaseProperties.getUsername());          Assert.assertEquals("Incorrectly bound Password property",            "password", databaseProperties.getPassword());      }    }

我們通過內部類 Server 還添加了嵌套屬性 database.server.iddatabase.server.port我們應該添加內部類 Server 以及一個 server 的屬性並且生成他的 getter 和 setter 方法。

在我們的測試中,讓我們快速檢查一下,確保我們也可以成功地設置和讀取嵌套屬性:

@Test  public void whenNestedPropertyQueriedThenReturnsPropertyValue()    throws Exception {      Assert.assertEquals("Incorrectly bound Server IP nested property",        "127.0.0.1", databaseProperties.getServer().getIp());      Assert.assertEquals("Incorrectly bound Server Port nested property",        3306, databaseProperties.getServer().getPort());  }

好了,現在我們準備好來使用處理器了。

5. 生成配置元數據

我們在前面提到過,配置處理器生成一個文件 – 它是使用註解處理實現的。

所以,在編譯我們的項目之後,我們將在目錄 target/classes/META-INF 下看到文件名為 spring-configuration-metadata.json 的文件:

{    "groups": [      {        "name": "database",        "type": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties"      },      {        "name": "database.server",        "type": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties$Server",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties",        "sourceMethod": "getServer()"      }    ],    "properties": [      {        "name": "database.password",        "type": "java.lang.String",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties"      },      {        "name": "database.server.ip",        "type": "java.lang.String",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties$Server"      },      {        "name": "database.server.port",        "type": "java.lang.Integer",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties$Server",        "defaultValue": 0      },      {        "name": "database.username",        "type": "java.lang.String",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties"      }    ],    "hints": []  }

接下來,讓我們看看更改 Java bean 上的註解如何影響元數據。

5.1. 關於配置元數據的其他信息

首先,讓我們將 JavaDoc 注釋添加到Server 上.

第二,讓我們給出一個 database.server.port 字段的默認值並最後添加 @Min@Max 註解:

public static class Server {        /**       * The IP of the database server       */      private String ip;        /**       * The Port of the database server.       * The Default value is 443.       * The allowed values are in the range 400-4000.       */      @Min(400)      @Max(800)      private int port = 443;        // standard getters and setters  }

如果我們檢查 spring-configuration-metadata.json 文件,我們將看到這些額外的信息得到了反映:

{    "groups": [      {        "name": "database",        "type": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties"      },      {        "name": "database.server",        "type": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties$Server",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties",        "sourceMethod": "getServer()"      }    ],    "properties": [      {        "name": "database.password",        "type": "java.lang.String",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties"      },      {        "name": "database.server.ip",        "type": "java.lang.String",        "description": "The IP of the database server",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties$Server"      },      {        "name": "database.server.port",        "type": "java.lang.Integer",        "description": "The Port of the database server. The Default value is 443.          The allowed values are in the range 400-4000",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties$Server",        "defaultValue": 443      },      {        "name": "database.username",        "type": "java.lang.String",        "sourceType": "com.baeldung.autoconfiguration.annotationprocessor.DatabaseProperties"      }    ],    "hints": []  }

我們可以找到 database.server.ipdatabase.server.port 屬性的不同之處。事實上,額外的信息是非常有幫助的。開發人員和 IDE 都更容易理解每個屬性的功能。

我們還應該確保觸發構建以獲得更新的文件。在Eclipse中,如果我們檢查自動生成選項時,每個保存操作都將觸發生成。在 IntelliJ 中,我們應該手動觸發構建。

5.2. 理解元數據格式

讓我們仔細看看 JSON 元數據文件,並討論其組成。

Groups 是用於分組其他屬性的較高級別的項,而不指定值本身。在我們的例子中,我們有數據庫組,它也是配置屬性的前綴。我們還有一個 database 組,它是通過內部類把 IPport 屬性作為一個組。

屬性是可以為其指定值的配置項。這些屬性配置在後綴為 .properties或 .yml* 文件中,並且可以有額外的信息,比如默認值和驗證,就像我們在上面的示例中看到的那樣。

提示是幫助用戶設置屬性值的附加信息。例如,如果我們有一組屬性的允許值,我們可以提供每個屬性的描述。IDE 將為這些提示提供自動選擇的幫助。

配置元數據上的每個組成都有自己的屬性。來解釋配置屬性的詳細用法。

6. 總結

在本文中,我們介紹了 Spring Boot 配置處理器及其創建配置元數據的功能。使用元數據可以使與配置參數的交互變得更加容易。

我們給出了一個生成的配置元數據的示例,並詳細解釋了它的格式和組成。

我們還看到了 IDE 上的自動完成支持是多麼有幫助。

與往常一樣,本文中提到的所有代碼片段都可以在我們的 GitHub 存儲庫

原文:https://www.baeldung.com/spring-boot-configuration-metadata

作者:Dionis Prifti

譯者:遺失的拂曉


9月福利,關注公眾號

後台回復:004,領取8月翻譯集錦!

往期福利回復:001,002, 003即可領取!

img