1. 概述
本快速教程將教您如何從 YAML 文件中注入地圖到 Spring Boot 中。
首先,我們將對 Spring Framework 中的 YAML 文件進行一些介紹。然後,我們將演示如何將 YAML 屬性綁定到 Map,並通過一個實際示例進行展示。
2. Spring 框架中的 YAML 文件
使用 YAML 文件存儲外部配置數據是 Spring 開發人員常見的做法。 基本上,Spring 支持 YAML 文檔作為屬性的替代方案,並使用 SnakeYAML 在其底層進行解析。
不廢話,讓我們看看一個典型的 YAML 文件是什麼樣:
server:
port: 8090
application:
name: myapplication
url: http://myapplication.com如我們所見,YAML 文件具有自我解釋性,並且更易於人類閲讀。事實上,YAML 提供了一種精巧且簡潔的方法來存儲層次化配置數據。
默認情況下,Spring Boot 從 application.properties 或 application.yml 在應用程序啓動時讀取配置屬性。但是,我們可以使用 @PropertySource 加載自定義 YAML 文件。
現在我們對 YAML 文件有所瞭解,讓我們看看如何將 YAML 屬性注入為 Spring Boot 中的 Map。
3. 如何從 YAML 文件中注入 Map
Spring Boot 通過提供一個便捷的註解 @ConfigurationProperties,將數據外部化提升到了一個新的水平。這個註解被引入是為了輕鬆地將外部屬性從配置文件的直接注入到 Java 對象中。
在本節中,我們將重點介紹如何使用 @ConfigurationProperties 註解將 YAML 屬性綁定到 Bean 類中。
首先,我們將定義一些鍵值屬性在 application.yml 中:
server:
application:
name: InjectMapFromYAML
url: http://injectmapfromyaml.dev
description: How To Inject a map from a YAML File in Spring Boot
config:
ips:
- 10.10.10.10
- 10.10.10.11
- 10.10.10.12
- 10.10.10.13
filesystem:
- /dev/root
- /dev/md2
- /dev/md4
users:
root:
username: root
password: rootpass
guest:
username: guest
password: guestpass在本示例中,我們將嘗試將 application 映射到一個簡單的 Map<String, String>。 同樣,我們將配置詳情注入為一個 Map<String, List<String>>,users 作為具有 String 鍵的 Map,以及屬於用户自定義類的對象(Credential)作為值。
然後,我們將創建一個 Bean 類,ServerProperties,以封裝將配置屬性綁定到 Map 的邏輯:
@Component
@ConfigurationProperties(prefix = "server")
public class ServerProperties {
private Map<String, String> application;
private Map<String, List<String>> config;
private Map<String, Credential> users;
// getters and setters
public static class Credential {
private String username;
private String password;
// getters and setters
}
}如我們所見,我們為 ServerProperties 類添加了 @ConfigurationProperties 註解。 這樣,我們告訴 Spring 將所有帶有指定前綴的屬性映射到一個 ServerProperties 對象的實例。
請記住,我們的應用程序需要啓用配置屬性,儘管這在大多數 Spring Boot 應用程序中都是自動完成的。
最後,我們將測試我們的 YAML 屬性是否已正確注入為 Map 對象:
@RunWith(SpringRunner.class)
@SpringBootTest
class MapFromYamlIntegrationTest {
@Autowired
private ServerProperties serverProperties;
@Test
public void whenYamlFileProvidedThenInjectSimpleMap() {
assertThat(serverProperties.getApplication())
.containsOnlyKeys("name", "url", "description");
assertThat(serverProperties.getApplication()
.get("name")).isEqualTo("InjectMapFromYAML");
}
@Test
public void whenYamlFileProvidedThenInjectComplexMap() {
assertThat(serverProperties.getConfig()).hasSize(2);
assertThat(serverProperties.getConfig()
.get("ips")
.get(0)).isEqualTo("10.10.10.10");
assertThat(serverProperties.getUsers()
.get("root")
.getUsername()).isEqualTo("root");
}
}4. @ConfigurationProperties vs @Value
現在我們快速比較一下 @ConfigurationProperties 和 @Value。
儘管這兩個註解都可以用來從配置文件中注入屬性,但它們之間存在顯著差異。這兩個註解的主要區別在於,每個註解都服務於不同的目的。
簡而言之,@Value 允許我們通過其鍵直接注入特定屬性的值。 然而,@ConfigurationProperties 註解將多個屬性綁定到一個特定的對象上,並通過映射的對象訪問這些屬性。
通常,Spring 建議在注入配置數據時使用 @ConfigurationProperties 而不是 @Value。 @ConfigurationProperties 提供了一種集中和組織配置屬性的方式,將其放入一個結構化的對象中,然後可以將其注入到其他 Bean 中。
5. 結論
在本文中,我們探討了如何在 Spring Boot 中注入來自 YAML 文件的 Map。 此外,我們還強調了 @ConfigurationProperties 和 @Value 的區別。