I have a spring application that is currently using *.properties files and I want to have it using YAML files instead.
I found the class YamlPropertiesFactoryBean that seems to be capable of doing what I need.
My problem is that I'm not sure how to use this class in my Spring application (which is using annotation based configuration). It seems I should configure it in the PropertySourcesPlaceholderConfigurer with the setBeanFactory method.
Previously I was loading property files using @PropertySource as follows:
@Configuration @PropertySource("classpath:/default.properties") public class PropertiesConfig { @Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }
How can I enable the YamlPropertiesFactoryBean in the PropertySourcesPlaceholderConfigurer so that I can load YAML files directly? Or is there another way of doing this?
Thanks.
My application is using annotation based config and I'm using Spring Framework 4.1.4. I found some information but it always pointed me to Spring Boot, like this one.
Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean will load YAML as Properties and the YamlMapFactoryBean will load YAML as a Map.
However, by default, @PropertySource doesn't load YAML files. This fact is explicitly mentioned in the official documentation. So, if we want to use the @PropertySource annotation in our application, we need to stick with the standard properties files.
If your key is loginUrl (inside your yaml file), you can inject its value with the @Value annotation, inside a Spring component. @Value("${loginUrl}") private String loginUrl; If it's a second level property, the path is @Value("${yourFirstKey. loginUrl}") .
To access the YAML properties, we'll create an object of the YAMLConfig class, and access the properties using that object. In the properties file, we'll set the spring. profiles. active environment variable to prod.
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
@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; }
`
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With