教你如何在 Spring BOOT 中處理配置
大約 8 年后,我目前正在重新使用 Java + Spring 進(jìn)行編碼。在過去的 8 年中,我花在編碼上的時(shí)間顯著增加,因?yàn)槲椰F(xiàn)在擔(dān)任的領(lǐng)導(dǎo)角色讓我遠(yuǎn)離了編寫代碼。話雖如此,我需要了解一定程度的編碼,尤其是在 Java 世界中,因?yàn)檫@是我的大部分項(xiàng)目都使用的語言,除非我熟悉編碼,否則我無法有效地幫助我的團(tuán)隊(duì)。自從我停止編碼以來發(fā)生了很大的變化,我正在重新學(xué)習(xí)一切。這是我將寫的許多文章中的第一篇,因?yàn)槲抑懒诵率挛?。此外,我更多地從我個(gè)人的成果中構(gòu)建了一個(gè)應(yīng)用程序。我通常不能花一致的時(shí)間,這讓我可以花更多的時(shí)間學(xué)習(xí),而不是試圖滿足現(xiàn)實(shí)生活中客戶項(xiàng)目的最后期限。
在這篇文章中,我將討論如何在 Spring Boot 應(yīng)用程序中使用外部化配置。
1.概述
我們將使用 Spring Boot 的默認(rèn)設(shè)置來創(chuàng)建一些配置并在我們的應(yīng)用程序中讀取它們。我們還將研究一種設(shè)置屬性和基于 YAML 的配置的簡單鍵值方式。
我更喜歡使用 YAML,從現(xiàn)在開始,我將只使用 YAML 基礎(chǔ)設(shè)置。
2. 初始設(shè)置
在我的實(shí)現(xiàn)運(yùn)行期間,我注意到我最終需要使用。
spring-boot-configuration-processor 依賴項(xiàng)。否則我會(huì)得到一個(gè)錯(cuò)誤,并且代碼不會(huì)編譯。我沒有找到太多關(guān)于為什么在我的研究中需要這樣做,但是添加這個(gè)依賴項(xiàng)為我解決了這個(gè)問題。
我添加的第二個(gè)依賴項(xiàng)是 Actuator,它為我們提供了一些令人興奮的工具。這是不必要的,但如果您正在尋找調(diào)試屬性并找到更多可使用的配置,我建議您也添加它。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;"><依賴></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<groupId>org.springframework.boot</groupId></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<artifactId>spring-boot-configuration-processor</artifactId></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<可選>真</可選></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
</依賴></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<依賴></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<groupId>org.springframework.boot</groupId></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
<artifactId>spring-boot-starter-actuator</artifactId></font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
</依賴></font></font>
3. 設(shè)置配置文件
以下代碼適用于 application.properties 文件,這是您將在 Spring Boot 中獲得的默認(rèn)格式。
<font style="vertical-align: inherit;"><font style="vertical-align: inherit;"># 這是為了暴露Actuator的所有端點(diǎn)。</font><font style="vertical-align: inherit;">僅在 DEV 中對(duì)所有人使用 *</font></font><font style="vertical-align: inherit;"><font style="vertical-align: inherit;">
management.endpoints.web.exposure.include=*</font></font>
# Custom Properties
bungie.rootPath="https://www.bungie.net/Platform"
bungie.apiKey=000999888111
以下是 YAML 格式的相同屬性。
bungie:
rootPath: "https://www.bungie.net/Platform"
apiKey: 000999888111
4. 創(chuàng)建將讀取這些配置的 Bean
現(xiàn)在我們已經(jīng)創(chuàng)建了屬性,在讀取屬性時(shí)我們需要考慮 2 個(gè)用例。
- 讀取一次性屬性——在這種情況下,我們可能需要?jiǎng)?chuàng)建一個(gè)需要讀取一次或不能與任何其他屬性分類的屬性。在這種情況下,您可以使用@Value 注解來讀取它。
- 讀取一組屬性——在我們的示例中,我們已經(jīng)在“bungie”類別下確定了兩個(gè)分組屬性。這就是我更喜歡創(chuàng)建屬性的方式。我不喜歡有孤兒屬性,因此我們只會(huì)看到如何設(shè)置它們。以下示例將向我們展示如何創(chuàng)建 。 Java Bean/Configuration,它將能夠讀取我們的屬性文件并填充對(duì)象。
package io.howtoarchitect.destinyclanwars.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties("bungie")
@Getter @Setter
public class BungieClientSettings {
private String rootPath;
private String apiKey;
}
如果你觀察上面的代碼塊,你會(huì)注意到一些事情:
- 我們?cè)?jīng)@Configuration讓 Spring 應(yīng)用程序知道這是一個(gè) bean,應(yīng)該這樣初始化。
- @Getter并且@Setter來自 Lombok 包,為我們提供了默認(rèn)的 Getter 和 Setter。這些是強(qiáng)制性的,因?yàn)?Spring 應(yīng)用程序總是需要這些 getter 和 setter。
- @ConfigurationProperties是這里的主要技巧的注釋。它將遍歷我們上下文中可用的所有屬性,并搜索任何已映射的用戶“bungie”。找到后,此注釋將映射 YAML/Properties 文件值并將它們添加到我們的字符串中。
5. 消費(fèi)屬性
完成此設(shè)置后,最后一步是在我們的應(yīng)用程序中讀取這些屬性。我們將在另一個(gè) Spring bean/service 中讀取這些屬性。
package io.howtoarchitect.destinyclanwars.bungieclient;
import io.howtoarchitect.destinyclanwars.config.BungieClientSettings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
@Service
public class BungieClient {
private static WebClient client;
@Autowired
private BungieClientSettings bungieClientSettings;
public WebClient getDefaultClient() {
client = WebClient.builder()
.baseUrl(bungieClientSettings.getRootPath())
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader("X-API-KEY", bungieClientSettings.getApiKey())
.build();
return client;
}
}
您會(huì)注意到我已將其添加BungieClientSettings為@Autowired依賴項(xiàng)。這會(huì)在我的類中注入 bean,當(dāng)我需要訪問這些屬性時(shí),我需要做的就是bungieClientSettings.getAPIKey()和bungieClientSettings.getRootPath()。
結(jié)論
這就是您需要做的就是將您的屬性外部化。盡早設(shè)置這一點(diǎn)很重要,因?yàn)槿绻贿@樣做,您最終會(huì)將其中許多分散在課堂上,并且遷移到多個(gè)環(huán)境將變得困難。