We are using spring boot 2.0.0
. We have three environments dev
, staging
, production
. Our current config structure
I think there are 2 ways you can achieve this requirement.
spring.profiles.active
accepts a comma-separated list of active profiles, so you can always provide dev,dev-sqs,dev-redis
as the value.
Another approach is by making use of @PropertySource
and a custom PropertySourceFactory
to achieve this requirement. You can find an implementation which takes the value from spring.profiles.active
to load one corresponding YAML file in the article below. It should be super easy to adapt the implementation to load multiple files by looking for the profile id in the name of the YAML files.
[How-to] Read profile-based YAML configurations with @PropertySource
Have you tried including profiles yet ?
Example with profile default
, you want to load additional properties for redis
and db
. Within application.properties
file, add:
spring.profiles.include=redis, db
This will load files application-redis.properties
and application-db.properties
respectively
I was dealing with a similar problem and I'd recommend using yaml configuration.
Let's describe .properties
file:
One can use it like this:
@Component
@PropertySources({
@PropertySource("classpath:application.properties"),
@PropertySource("classpath:application-${spring.profiles.active}.properties")
})
public class AppProperties {
}
This is very easy to configure. Limitation is, that you cannot combine profiles. I mean, that when you want to use profile as dev,local
where local
just alters some config properties for dev
profile, Spring will try to load application-dev,local.properties
file, which is very likely not what you want.
Btw, this is what Spring will do for you automatically, this is useful for topics as you described.
There is no way to configure it per profile (and not for whole list). Other possibility would be, that one can specify the list in spring.config.name
which is not the case at the moment.
In short, use:
@Profile("dev")
@Configuration
@PropertySources({
@PropertySource("classpath:topic1-dev.properties"),
@PropertySource("classpath:topic2-dev.properties")
})
public class AppPropertiesDev {
}
Disadvantage is, you have to have several such config classes (dev, staging), but know you have the topics. Also you can use mutliple profiles, which are (as of my testing) loaded in order you specified. That way, your developer can easily use dev configuration and alter just what's needed for his/her testing.
You can see the approach with yaml in question I asked earlier - Property resolving for multiple Spring profiles (yaml configuration), benefit is smaller amount of files - yaml has all the profiles in one file, which may or may not be what you want.
Yes, it's possible. spring.config.location
is used to externalize the config file location in Spring boot applications. This can be used to provide a location of the file in the filesystem or even in the classpath. Based on how you want to provide your application access to the files, you can choose the URI.
Doing it programmatically:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(Application.class)
.properties("spring.config.location:classpath:/application-dev.yml,classpath:/application-dev-sqs.yml,classpath:/application-dev-redis.yml")
.build()
.run(args);
}
}
Doing it via environment variables:
set SPRING_CONFIG_LOCATION=classpath:/application-dev.yml, \
classpath:/application-dev-sqs.yml, \
classpath:/application-dev-redis.yml
So, you can provide your files as comma-separated values.
I've used classpath
here, it can also be a location in the file system:
/home/springboot-app/properties/application-dev.yml,/home/springboot-app/properties/application-sqs.yml,/home/springboot-app/properties/application-redis.yml