The Scenario
Sometimes, some developers like to use Yaml property files in Spring-boot.
This tutorial tells how: how to load properties for correct profile and make their properties avaliable in Environment. So wen can use appContext.getEnvironment().getProperty to get property value in static or non-spring-managed context.
The implementation
EnvironmentAwarePropertySourcesPlaceholderConfigurer
First we will create EnvironmentAwarePropertySourcesPlaceholderConfigurer: we can use its addYamlPropertySource to add yaml file which will load properties defined for de the active profile and default properties.
Then we create static PropertySourcesPlaceholderConfigurer and load yaml files. Due to spring restriction, we can't use yaml file in @PropertySource
Resources
Leverage Spring Boot’s YAML Configuration Files in Groovy Scripts
Sometimes, some developers like to use Yaml property files in Spring-boot.
This tutorial tells how: how to load properties for correct profile and make their properties avaliable in Environment. So wen can use appContext.getEnvironment().getProperty to get property value in static or non-spring-managed context.
The implementation
EnvironmentAwarePropertySourcesPlaceholderConfigurer
First we will create EnvironmentAwarePropertySourcesPlaceholderConfigurer: we can use its addYamlPropertySource to add yaml file which will load properties defined for de the active profile and default properties.
/**
* From http://jdpgrailsdev.github.io/blog/2014/12/30/groovy_script_spring_boot_yaml.html. This will
* add propertySources into environment, so we can use environment().getProperty to get property
* value in some cases.
*/
public class EnvironmentAwarePropertySourcesPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer
implements EnvironmentAware, InitializingBean {
private List<PropertySource<?>> propertySources = new ArrayList<>();
private ConfigurableEnvironment environment;
public EnvironmentAwarePropertySourcesPlaceholderConfigurer() {}
/**
* @param propertySources: order: abc-default.yaml, abc-{env}.yaml <br>
* This makes its usage same as org.springframework.context.annotation.PropertySource
*/
public EnvironmentAwarePropertySourcesPlaceholderConfigurer(@Nonnull final List<PropertySource<?>> propertySources) {
this.propertySources = propertySources;
}
@Override
public void setEnvironment(final Environment environment) {
// all subclasses extend ConfigurableEnvironment
this.environment = (ConfigurableEnvironment) environment;
super.setEnvironment(environment);
}
public EnvironmentAwarePropertySourcesPlaceholderConfigurer addYamlPropertySource(@Nonnull Resource resource)
throws IOException {
return addYamlPropertySource(resource.getFilename(), resource);
}
public EnvironmentAwarePropertySourcesPlaceholderConfigurer addYamlPropertySource(@Nonnull String name,
@Nonnull Resource resource) throws IOException {
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
// order: abc-default.yaml, abc-{env}.yaml
PropertySource<?> defaultYamlPropertySource = loader.load(name + ".defualt", resource, null);
propertySources.add(defaultYamlPropertySource);
PropertySource<?> applicationYamlPropertySource =
loader.load(name + "." + System.getProperty("env"), resource, System.getProperty("env"));
propertySources.add(applicationYamlPropertySource);
return this;
}
@Override
public void afterPropertiesSet() throws Exception {
// This will ad it as abc-{env}.properties, abc-default.properties into
// environment.propertySource
// spring get value from the first propertySource which defines the property and return it.
// check org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(String,
// Class<T>, boolean)
if (propertySources != null) {
propertySources.forEach(propertySource -> environment.getPropertySources().addFirst(propertySource));
}
}
}
PropertySourcesPlaceholderConfigurerThen we create static PropertySourcesPlaceholderConfigurer and load yaml files. Due to spring restriction, we can't use yaml file in @PropertySource
public static PropertySourcesPlaceholderConfigurer propertyConfig() throws IOException {
final String password = System.getenv(ENV_APP_ENCRYPTION_PASSWORD);
if (StringUtils.isBlank(password)) {
return new EnvironmentAwarePropertySourcesPlaceholderConfigurer()
.addYamlPropertySource(new ClassPathResource("cassandra.yaml")); // add more
}
return new EncryptedPropertySourcesPlaceholderConfigurer(password)
.addYamlPropertySource(new ClassPathResource("cassandra.yaml"));
}
Check Spring - Encrypt Properties by Customizing PropertySourcesPlaceholderConfigurer to know more how to implement EncryptedPropertySourcesPlaceholderConfigurer. Resources
Leverage Spring Boot’s YAML Configuration Files in Groovy Scripts