How to use YamlPropertiesFactoryBean to load YAML files using Spring Framework 4.1?
With XML config I've been using this construct:
<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"/>
Of course you have to have the snakeyaml dependency on your runtime classpath.
I prefer XML config over the java config, but I recon it shouldn't be hard to convert it.
edit:
java config for completeness sake
@Beanpublic static PropertySourcesPlaceholderConfigurer properties() { PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); yaml.setResources(new ClassPathResource("default.yml")); propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject()); return propertySourcesPlaceholderConfigurer;}
`
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-Example-File.yml
person: firstName: Mahmoud middleName:Ahmed
Reference my example on github spring-boot-yaml-sample So you can load yaml files and inject values using @Value()
To read .yml file in Spring you can use next approach.
For example you have this .yml file:
section1: key1: "value1" key2: "value2"section2: key1: "value1" key2: "value2"
Then define 2 Java POJOs:
@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.}
Now you can autowire these beans in your component. For example:
@Componentpublic class MyPropertiesAggregator { @Autowired private MyCustomSection1 section;}
In case you are using Spring Boot everything will be auto scaned and instantiated:
@SpringBootApplicationpublic class MainBootApplication { public static void main(String[] args) { new SpringApplicationBuilder() .sources(MainBootApplication.class) .bannerMode(OFF) .run(args); }}
If you'are using JUnit there is a basic test setup for loading YAML file:
@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(MainBootApplication.class)public class MyJUnitTests { ...}
If you're using TestNG there is a sample of test configuration:
@SpringApplicationConfiguration(MainBootApplication.class)public abstract class BaseITTest extends AbstractTestNGSpringContextTests { ....}