从YAML文件读取内容映射为Map
如何在Spring Boot中从YAML文件注入到Map。
首先,将对Spring框架中的YAML文件有一些了解。 然后,通过一个实际示例展示如何将YAML属性绑定到Map。
Spring框架中的YAML文件
使用YAML文件存储外部配置数据是一种常见的做法。 基本上,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文件,看看如何在Spring Boot中将YAML属性作为Map注入。
从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
其次,创建一个bean类MapServerProperties来封装将配置属性绑定到Maps的逻辑:
@Configuration
@ConfigurationProperties(prefix = "server")
@Data
public class MapServerProperties {
private Map<String, String> application;
private Map<String, List<String>> config;
private Map<String, Credential> users;
@Data
public static class Credential {
private String username;
private String password;
}
}
如上面所见,我们用@ConfigurationProperties装饰了MapServerProperties类。 这样,告诉Spring将具有指定前缀的所有属性映射到MapServerProperties的对象。
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MapFromYamlIntegrationTest {
@Autowired
private MapServerProperties mapServerProperties;
@Test
public void whenYamlFileProvidedThenInjectSimpleMap() {
assertThat(mapServerProperties.getApplication())
.containsOnlyKeys("name", "url", "description");
assertThat(mapServerProperties.getApplication()
.get("name")).isEqualTo("InjectMapFromYAML");
}
@Test
public void whenYamlFileProvidedThenInjectComplexMap() {
assertThat(mapServerProperties.getConfig()).hasSize(2);
assertThat(mapServerProperties.getConfig()
.get("ips")
.get(0)).isEqualTo("10.10.10.10");
assertThat(mapServerProperties.getUsers()
.get("root")
.getUsername()).isEqualTo("root");
}
}
@ConfigurationProperties与@Value
快速比较@ConfigurationProperties和@Value。
尽管两个注解均可用于从配置文件注入属性,但它们却大不相同。 这两个注释之间的主要区别在于,每个注释具有不同的用途。
简而言之,@Value允许我们通过键直接注入特定的属性值。 但是,@ConfigurationProperties批注将多个属性绑定到特定对象,并提供通过映射对象对属性的访问。
通常,在注入配置数据时,Spring建议在@Value上使用@ConfigurationProperties。 @ConfigurationProperties提供了一种在结构化对象中集中和分组配置属性的好方法,以后我们可以将其注入其他bean。
配置文件yml中的map形式
yml中的格式
tes:
maps: {key1: 12,key2: 34}
或者
tes:
maps:
key1: 15
key2: 2
创建一个类
然后创建对应类型的字段(注意下这个类的那两个注释了的注解)
package com.etc.lzg;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
import java.util.Map;
@Data
@Component
//@Configuration //这个我这里虽然存在时能成功,不过我注释了也是可以的,这个是看网上有人写就跟着写上的
//@PropertySource(value = {"classpath:/application.yml"}, encoding = "utf-8") //有的人是写了这个注解能成功,但是我这边不能有这个注解,有的话,就连编译都会报错
@ConfigurationProperties(prefix = "tes")
public class MapTest {
private Map<String, String> maps;
}
引用
package com.etc.lzg;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class LzgApplicationTests {
@Autowired
private MapTest mapTest;
@Test
public void contextLoads() {
System.out.println(mapTest.toString());
System.out.println("key1="+mapTest.getMaps().get("key1"));
}
}
打印
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。