Reputation: 471
I work on a SpringBoot application which has to run on different environments. The property files are created and once I modify the environment the default values are overridden with the proper ones. That's okay.
In the next step I want to check whether the logged in user System.getProperty("user.name")
has a custom property file. If so, these properties must be overriden with his ones. So the steps should be (let's say the active profile is dev):
I read many topcis and found two possible solutions, but none of them worked.
@PropertySource("user.properties")
to a configuration class, which should load the user specific property file and override the values. For testing purposes, I added server.port=1234
to user.properties, but this was ignored.`
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholder() {
PropertyPlaceholderConfigurer propertyPlaceholder = new PropertyPlaceholderConfigurer();
propertyPlaceholder.setLocations(
new ClassPathResource("application.properties"),
new ClassPathResource("application-dev.properties"),
new ClassPathResource("user.properties"));
propertyPlaceholder.setIgnoreResourceNotFound(true);
propertyPlaceholder.setIgnoreUnresolvablePlaceholders(true);
return propertyPlaceholder;
}
I don't know how to go forward. So any idea is really welcomed.
Update: I've justed pushed the demo code to GitHub. Maybe is helps to find the solution: https://github.com/aszidien/springboot.
Upvotes: 1
Views: 4763
Reputation: 51481
Correct way to customise environment in Spring Boot is with an EnvironmentPostProcessor
that will run very early in ApplicationContext start-up and allow you to manage the property sources.
Step 1. Create file src/main/resources/META-INF/spring.factories
with the following:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.YourEnvironmentPostProcessor
Step 2. As an example create a file src/main/resources/custom.properties
with:
server.port=8081
Step 3. Now create you post processor class
package com.example;
public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
private final PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
Resource path = new ClassPathResource("custom.properties");
// ^^^ here you can create the resource however you want
// construct the name from a user name, use FileSystemResource, anything
// for example you can ask users to place a file in their home
// directory named "my-application.properties" and load it like so
// Resource path = new FileSystemResource(Paths.get(System.getProperty("user.home"),"my-application.properties").toString());
PropertySource<?> propertySource = loadProps(path);
environment.getPropertySources().addFirst(propertySource);
}
private PropertySource<?> loadProps(Resource path) {
if (!path.exists()) {
throw new IllegalArgumentException("Resource " + path + " does not exist");
}
try {
return this.loader.load("custom-resource", path, null);
}
catch (IOException ex) {
throw new IllegalStateException(
"Failed to load props configuration from " + path, ex);
}
}
}
Now when you run your application the port will change to 8081
and any other properties will override the defaults provided in your main properties.
Upvotes: 1