Multiple properties file for a single spring profile

前端 未结 4 535
广开言路
广开言路 2020-12-20 06:53

We are using spring boot 2.0.0. We have three environments dev, staging, production. Our current config structure

相关标签:
4条回答
  • 2020-12-20 07:12

    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

    0 讨论(0)
  • 2020-12-20 07:18

    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

    0 讨论(0)
  • 2020-12-20 07:27

    I was dealing with a similar problem and I'd recommend using yaml configuration.

    Let's describe .properties file:

    Initital approach

    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.

    Better approach

    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.

    Yaml approach

    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.

    0 讨论(0)
  • 2020-12-20 07:39

    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
    
    0 讨论(0)
提交回复
热议问题