1.概述
如何在Spring Boot中使用@PropertySource注解读取YAML属性文件。
2.@PropertySource和YAML格式
Spring Boot对外部化配置提供了强大的支持。 另外,可以使用不同的方式和格式直接读取Spring Boot应用程序中的属性。
但是,默认情况下,@PropertySource不会加载YAML文件。
2.5.2. Directly Loading YAML
Spring Framework provides two convenient classes that can be used to load YAML documents. The
YamlPropertiesFactoryBean
loads YAML asProperties
and theYamlMapFactoryBean
loads YAML as aMap
.You can also use the
YamlPropertySourceLoader
class if you want to load YAML as a SpringPropertySource
.Spring Framework提供了两个方便的类,可用于加载YAML文档。 YamlPropertiesFactoryBean将YAML作为属性加载,而YamlMapFactoryBean将YAML作为Map加载。
如果要将YAML加载为Spring PropertySource,也可以使用YamlPropertySourceLoader类。
因此,如果想在应用程序中使用@PropertySource注解,则需要坚持使用标准属性文件。 或者可以自己实现。
3.自定义PropertySourceFactory
从Spring 4.3开始,@PropertySource带有factory属性。 可以利用它来提供PropertySourceFactory的自定义实现,该实现将处理YAML文件处理。
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource)
throws IOException {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());
Properties properties = factory.getObject();
return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
}
}
正如上面,实现一个createPropertySource方法就足够了。
在自定义实现中,首先,使用YamlPropertiesFactoryBean将YAML格式的资源转换为java.util.Properties对象。
然后,简单地返回了PropertiesPropertySource的新实例,该实例是一个包装,允许Spring读取解析的属性。
4.@PropertySource和YAML的实际应用
看看如何在实践中使用它们。
首先,创建一个简单的YAML文件– foo.yml:
yaml:
name: foo
aliases:
- abc
- xyz
接下来,使用@ConfigurationProperties创建一个属性类,并使用的自定义YamlPropertySourceFactory:
@Configuration
@ConfigurationProperties(prefix = "yaml")
@PropertySource(value = "classpath:foo.yml", factory = YamlPropertySourceFactory.class)
@Data
public class YamlFooProperties {
private String name;
private List<String> aliases;
}
最后,验证属性是否已正确注入:
@RunWith(SpringRunner.class)
@SpringBootTest
public class YamlFooPropertiesIntegrationTest {
@Autowired
private YamlFooProperties yamlFooProperties;
@Test
public void whenFactoryProvidedThenYamlPropertiesInjected() {
assertThat(yamlFooProperties.getName()).isEqualTo("foo");
assertThat(yamlFooProperties.getAliases()).containsExactly("abc", "xyz");
}
}