如何使用 YamlPropertiesFactoryBean 加载使用 Spring Framework 4.1 的 YAML 文件?
How to use YamlPropertiesFactoryBean to load YAML files using Spring Framework 4.1?
我有一个 spring 应用程序当前正在使用 *.properties 文件,我想使用 YAML 文件代替它。
我发现 class YamlPropertiesFactoryBean 似乎能够满足我的需要。
我的问题是我不确定如何在我的 Spring 应用程序(使用基于注释的配置)中使用此 class。
看来我应该在 PropertySourcesPlaceholderConfigurer with the setBeanFactory 方法中配置它。
之前我使用 @PropertySource 加载 属性 个文件,如下所示:
@Configuration
@PropertySource("classpath:/default.properties")
public class PropertiesConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
如何在 PropertySourcesPlaceholderConfigurer 中启用 YamlPropertiesFactoryBean 以便我可以直接加载 YAML 文件?
或者还有其他方法吗?
谢谢。
我的应用程序使用基于注释的配置,我使用的是 Spring Framework 4.1.4。
我找到了一些信息,但它总是指向 Spring Boot,例如 this one.
使用 XML 配置我一直在使用这个结构:
<context:annotation-config/>
<bean id="yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources" value="classpath:test.yml"/>
</bean>
<context:property-placeholder properties-ref="yamlProperties"/>
当然你必须在你的运行时类路径上有 snakeyaml 依赖。
我更喜欢 XML 配置而不是 java 配置,但我认为转换它应该不难。
编辑:
java 为了完整起见进行配置
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("default.yml"));
propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
return propertySourcesPlaceholderConfigurer;
}
要读取 Spring 中的 .yml 文件,您可以使用下一种方法。
例如,您有这个 .yml 文件:
section1:
key1: "value1"
key2: "value2"
section2:
key1: "value1"
key2: "value2"
然后定义2个Java个POJO:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "section1")
public class MyCustomSection1 {
private String key1;
private String key2;
// define setters and getters.
}
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "section2")
public class MyCustomSection1 {
private String key1;
private String key2;
// define setters and getters.
}
现在您可以在组件中自动装配这些 bean。例如:
@Component
public class MyPropertiesAggregator {
@Autowired
private MyCustomSection1 section;
}
如果您使用 Spring 启动,所有内容都将被自动扫描和实例化:
@SpringBootApplication
public class MainBootApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(MainBootApplication.class)
.bannerMode(OFF)
.run(args);
}
}
如果您使用的是 JUnit,则有一个用于加载 YAML 文件的基本测试设置:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(MainBootApplication.class)
public class MyJUnitTests {
...
}
如果您使用的是 TestNG,则有一个测试配置示例:
@SpringApplicationConfiguration(MainBootApplication.class)
public abstract class BaseITTest extends AbstractTestNGSpringContextTests {
....
}
`
package com.yaml.yamlsample;
import com.yaml.yamlsample.config.factory.YamlPropertySourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
@PropertySource(value = "classpath:My-Yaml-Example-File.yml", factory = YamlPropertySourceFactory.class)
public class YamlSampleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(YamlSampleApplication.class, args);
}
@Value("${person.firstName}")
private String firstName;
@Override
public void run(String... args) throws Exception {
System.out.println("first Name :" + firstName);
}
}
package com.yaml.yamlsample.config.factory;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
import java.util.List;
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null) {
return super.createPropertySource(name, resource);
}
List<PropertySource<?>> propertySourceList = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
if (!propertySourceList.isEmpty()) {
return propertySourceList.iterator().next();
}
return super.createPropertySource(name, resource);
}
}
My-Yaml-示例-File.yml
person:
firstName: Mahmoud
middleName:Ahmed
参考我在 github 上的示例 spring-boot-yaml-sample 因此您可以加载 yaml 文件并使用 @Value()
注入值
我花了 5 到 6 个小时来理解为什么 yml/yaml 文件(而不是 application.yml)的外部配置如此 different.I 阅读各种文章,堆栈溢出问题但没有得到正确答案。
我被困在两者之间,就像我能够使用 YamlPropertySourceLoader 使用自定义 yml 文件值但不能使用 @Value 因为它给我错误
注入自动装配的依赖项失败;嵌套异常是 java.lang.IllegalArgumentException: 无法解析占位符
'fullname.firstname' 值“${fullname.firstname}”
fullname 是 yml 中的 属性。
然后我使用 "turtlesallthewaydown" 上面给出的解决方案,最后我能够使用 @Value 没有任何问题的 yaml 文件,我删除了 YamlPropertySourceLoader。
现在我了解了 YamlPropertySourceLoader 和 PropertySourcesPlaceholderConfigurer 之间的区别,非常感谢,但是我已经在我的 git 存储库中添加了这些更改。
Git 回购:
https://github.com/Atishay007/spring-boot-with-restful-web-services
Class 姓名:SpringMicroservicesApplication.java
如果想知道如何将yaml文件加载到Spring中的Properties中,那么有一个解决方案:
public Properties loadYaml(String fileName){
// fileName for eg is "my-settings.yaml"
YamlPropertySourceLoader ypsl = new YamlPropertySourceLoader();
PropertySource ps = ypsl.load(fileName, new ClassPathResource(fileName)).get(0);
Properties props = new Properties();
props.putAll((Map)ps.getSource());
return props;
}
我有一个 spring 应用程序当前正在使用 *.properties 文件,我想使用 YAML 文件代替它。
我发现 class YamlPropertiesFactoryBean 似乎能够满足我的需要。
我的问题是我不确定如何在我的 Spring 应用程序(使用基于注释的配置)中使用此 class。 看来我应该在 PropertySourcesPlaceholderConfigurer with the setBeanFactory 方法中配置它。
之前我使用 @PropertySource 加载 属性 个文件,如下所示:
@Configuration
@PropertySource("classpath:/default.properties")
public class PropertiesConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
如何在 PropertySourcesPlaceholderConfigurer 中启用 YamlPropertiesFactoryBean 以便我可以直接加载 YAML 文件? 或者还有其他方法吗?
谢谢。
我的应用程序使用基于注释的配置,我使用的是 Spring Framework 4.1.4。 我找到了一些信息,但它总是指向 Spring Boot,例如 this one.
使用 XML 配置我一直在使用这个结构:
<context:annotation-config/>
<bean id="yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources" value="classpath:test.yml"/>
</bean>
<context:property-placeholder properties-ref="yamlProperties"/>
当然你必须在你的运行时类路径上有 snakeyaml 依赖。
我更喜欢 XML 配置而不是 java 配置,但我认为转换它应该不难。
编辑:
java 为了完整起见进行配置
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("default.yml"));
propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
return propertySourcesPlaceholderConfigurer;
}
要读取 Spring 中的 .yml 文件,您可以使用下一种方法。
例如,您有这个 .yml 文件:
section1:
key1: "value1"
key2: "value2"
section2:
key1: "value1"
key2: "value2"
然后定义2个Java个POJO:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "section1")
public class MyCustomSection1 {
private String key1;
private String key2;
// define setters and getters.
}
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "section2")
public class MyCustomSection1 {
private String key1;
private String key2;
// define setters and getters.
}
现在您可以在组件中自动装配这些 bean。例如:
@Component
public class MyPropertiesAggregator {
@Autowired
private MyCustomSection1 section;
}
如果您使用 Spring 启动,所有内容都将被自动扫描和实例化:
@SpringBootApplication
public class MainBootApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(MainBootApplication.class)
.bannerMode(OFF)
.run(args);
}
}
如果您使用的是 JUnit,则有一个用于加载 YAML 文件的基本测试设置:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(MainBootApplication.class)
public class MyJUnitTests {
...
}
如果您使用的是 TestNG,则有一个测试配置示例:
@SpringApplicationConfiguration(MainBootApplication.class)
public abstract class BaseITTest extends AbstractTestNGSpringContextTests {
....
}
`
package com.yaml.yamlsample;
import com.yaml.yamlsample.config.factory.YamlPropertySourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;
@SpringBootApplication
@PropertySource(value = "classpath:My-Yaml-Example-File.yml", factory = YamlPropertySourceFactory.class)
public class YamlSampleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(YamlSampleApplication.class, args);
}
@Value("${person.firstName}")
private String firstName;
@Override
public void run(String... args) throws Exception {
System.out.println("first Name :" + firstName);
}
}
package com.yaml.yamlsample.config.factory;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
import java.util.List;
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
@Override
public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException {
if (resource == null) {
return super.createPropertySource(name, resource);
}
List<PropertySource<?>> propertySourceList = new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource());
if (!propertySourceList.isEmpty()) {
return propertySourceList.iterator().next();
}
return super.createPropertySource(name, resource);
}
}
My-Yaml-示例-File.yml
person:
firstName: Mahmoud
middleName:Ahmed
参考我在 github 上的示例 spring-boot-yaml-sample 因此您可以加载 yaml 文件并使用 @Value()
注入值我花了 5 到 6 个小时来理解为什么 yml/yaml 文件(而不是 application.yml)的外部配置如此 different.I 阅读各种文章,堆栈溢出问题但没有得到正确答案。
我被困在两者之间,就像我能够使用 YamlPropertySourceLoader 使用自定义 yml 文件值但不能使用 @Value 因为它给我错误 注入自动装配的依赖项失败;嵌套异常是 java.lang.IllegalArgumentException: 无法解析占位符 'fullname.firstname' 值“${fullname.firstname}”
fullname 是 yml 中的 属性。
然后我使用 "turtlesallthewaydown" 上面给出的解决方案,最后我能够使用 @Value 没有任何问题的 yaml 文件,我删除了 YamlPropertySourceLoader。
现在我了解了 YamlPropertySourceLoader 和 PropertySourcesPlaceholderConfigurer 之间的区别,非常感谢,但是我已经在我的 git 存储库中添加了这些更改。
Git 回购: https://github.com/Atishay007/spring-boot-with-restful-web-services
Class 姓名:SpringMicroservicesApplication.java
如果想知道如何将yaml文件加载到Spring中的Properties中,那么有一个解决方案:
public Properties loadYaml(String fileName){
// fileName for eg is "my-settings.yaml"
YamlPropertySourceLoader ypsl = new YamlPropertySourceLoader();
PropertySource ps = ypsl.load(fileName, new ClassPathResource(fileName)).get(0);
Properties props = new Properties();
props.putAll((Map)ps.getSource());
return props;
}