Reputation: 23
I have an application with the newest SpringBoot v.2.1.9. The project contains a severals custom files with pattern as follow:
I want to reach the similiar behaviour to the Spring's application-{profile}.properties, I mean to load every custom props from file, which matches to active profile. Due to a huge number of properties I am not able to store them in application-{profile}.properties, because it causes a troubles with readability.
I'd like to find a strictly Java's solution, without any Maven's workarounds with physical replacing of files after the build. Could you please advise me how can I reach that approach?
My current assumption is to override an initialize method from ApplicationContextInitializer, then check the profile and execute the logic to select the files, however I am not sure if it's the most effecient approach.
Many thanks in advance for your help.
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
String profile = System.getProperty("spring.profiles.active");
//selecting files according to active profile
applicationContext.getEnvironment().getPropertySources().addLast(prop);
}
Upvotes: 1
Views: 985
Reputation: 1305
At the time of this response I am using spring-boot-starter-web:2.7.8
I use a "WebConfig" file like so:
@Configuration
@PropertySource(value = "classpath:somecustom.properties")
@PropertySource(value = "classpath:somecustom-${spring.profiles.active}.properties",
ignoreResourceNotFound = true)
public class WebConfig implements WebMvcConfigurer
{
@Autowired
protected Environment env;
...
This approach does not affect the built in behavior with property files named application.properties.
In the resources folder I have:
application.properties
application-l1.properties
application-l2.properties
application-l3.properties
application-loc.properties
somecustom.properties
somecustom-l1.properties
somecustom-l2.properties
somecustom-l3.properties
somecustom-loc.properties
By using @PropertySource I specify somecustom.properties to be the default and it must exist in the resources.
Then using the variable ${spring.profiles.active} will load, if found, properties for the specified environment.
Order matters, so put the default first.
Upvotes: 0
Reputation: 23
I have already solved my issue. If anyone would encounter the same troubles, please find my solution below:
1) Implement the EnvironmentPostProcessor and override the postProcessEnvironment method.
2) Get the files from resources -> I have used PathMatchingResourcePatternResolver class from org.springframework.core.io.support package. Once we pass the ClassLoader instance, we can execute the getResources(String path) method.
3) Iterate over Resource[] array and select those who fulfil your needs
4) Create a PropertiesPropertySourceLoader instance and load the properties from resource's path.
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Resource[] resources = getResources("classpath*:/properties/*.*");
List<List<PropertySource<?>>> propertySources = getPropertySources(resources);
for (int i = 0; i < propertySources.size(); i++) {
propertySources.get(i).forEach(propertySource -> environment.getPropertySources().addLast(propertySource));
}
application.setEnvironment(environment);
}
private Resource[] getResources(String path) {
ClassLoader classLoader = this.getClass().getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
try {
return resolver.getResources(path);
} catch (IOException ex) {
throw new IllegalStateException("Failed to load props configuration " + ex);
}
}
Upvotes: 1