具有多个配置文件的Spring Boot application.properties

时间:2019-12-16 11:56:36

标签: spring-boot profile

一个简单的问题:是否可以使spring boot属性文件依赖于两个或多个配置文件?像application-profile1-profile2.properties这样的东西?

2 个答案:

答案 0 :(得分:1)

Spring Boot不支持此功能。它仅支持here中所述的单个配置文件。

但是,它确实提供了足够的灵活性,可以使用EnvironmentPostProcessor添加自己的属性源。

以下是如何实现此示例:

public class MultiProfileEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
    private final ResourceLoader resourceLoader = new DefaultResourceLoader();

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        String[] activeProfiles = environment.getActiveProfiles();

        for (int i = 2; i <= activeProfiles.length; i++) {
            Generator.combination(activeProfiles).simple(i)
                    .forEach(profileCombination -> {
                        String propertySourceName = String.join("-", profileCombination);
                        String location = "classpath:/application-" + propertySourceName + ".properties";

                        if (resourceLoader.getResource(location).exists()) {
                            try {
                                environment.getPropertySources().addFirst(new ResourcePropertySource(propertySourceName, location));
                            } catch (IOException e) {
                                throw new RuntimeException("could not add property source '" + propertySourceName + "'", e);
                            }
                        }
                    });
        }
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

注意事项:

  • 此实现仅支持.properties文件,但也可以轻松扩展到.yml文件。
  • getActiveProfiles已经按最后一个获胜的顺序返回了配置文件。此实现依赖于此顺序,并利用此顺序构建不同的文件名。例如,如果活动配置文件为:profile1,profile2,profile3,则支持application-profile1-profile3.properties但不支持application-profile3-profile1.properties,并且application-profile1-profile3.properties将覆盖application-profile1.properties或{{1}中定义的属性}。
  • 此实现使用第三方库application-profile3.properties创建不同的配置文件集。
  • 将属性源添加到属性源列表的前面,以覆盖现有源。但是,如果您拥有优先使用的自定义属性源,则需要对其进行一些修改以按顺序考虑它们,例如,利用com.github.dpaukov:combinatoricslib3之类的方法。
  • 使用Environment.addAfter文件注册EnvironmentPostProcessor。

答案 1 :(得分:1)

我知道有 4 种方式。

  1. 像 Asi Bross Said 一样以编程方式插入 .yaml.properties。使用 ResourceLoaderYamlPropertySourceLoader 插入。

  2. 使用 .yaml。但是当您有另一个 spring 项目依赖它时,它将被替换。

  3. 使用属性而不是配置文件。 (对于api项目)

    1. 使用一个 @PropertySource 来定义属性文件 A。
    2. 从属性文件 A 中获取变量并将它们分配给另一个 @PropertySource 文件路径表达式中的参数。

    例如:

    resources
    /-application.properties  <-- remove or empty,because it will be override by application project
    /-moduleA
         /-application.properties               <-- Intellij can identify properties files started with application-
         /-application-mysql-dev.properties
         /-application-psql-dev.properties
         /-application-psql-prod.properties
    

    resources/moduleA/application.properties 的内容:

    moduleA.custom.profile1=mysql
    moduleA.custom.profile2=dev
    

    Java 配置文件的内容:

    @SpringBootApplication
    @PropertySources({
            @PropertySource("/moduleA/application.properties"),
            @PropertySource("/moduleA/application-${moduleA.custom.profile1}-${moduleA.custom.profile2}.properties"),
    })
    public class ModuleConfig {}
    
  4. 使用属性而不是配置文件。 (申请项目)

    resources
    /-application.properties
    /-application-mysql-dev.properties
    /-application-psql-dev.properties
    /-application-psql-prod.properties
    

    resources/application.properties 的内容:

    moduleA.custom.profile1=mysql
    moduleA.custom.profile2=dev
    

    SpringMvcApplication.java 的内容:

    @SpringBootApplication
    @PropertySource("/application-${moduleA.custom.profile1}-${moduleA.custom.profile2}.properties")
    public class SpringMvcApplication {...}