Spring Boot覆盖特定于用户的文件

时间:2017-08-16 18:51:14

标签: java spring spring-boot properties spring-profiles

我在SpringBoot应用程序上工作,该应用程序必须在不同的环境中运行。创建属性文件,一旦我修改环境,默认值将被正确的值覆盖。没关系。

在下一步中,我想检查登录用户System.getProperty("user.name")是否有自定义属性文件。如果是这样,那么必须用他的属性覆盖这些属性。所以步骤应该是(假设活动配置文件是 dev ):

  1. 加载application.properties
  2. 从application-dev.properties
  3. 加载和覆盖属性
  4. 如果用户有自定义属性文件(user.properties),请加载此属性并覆盖属性
  5. 我阅读了许多topcis并找到了两种可能的解决方案,但都没有。

    1. 将注释@PropertySource("user.properties")添加到配置类,该配置类应加载特定于用户的属性文件并覆盖这些值。出于测试目的,我将server.port=1234添加到user.properties,但这被忽略了。
    2. 创建自定义PropertyPlaceholderConfigurer。虽然此bean已成功创建,但服务器端口未更改。
    3. `

      @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;
      }
      

      我不知道如何前进。所以任何想法都非常受欢迎。

      更新:我已经把演示代码推到了GitHub上。也许有助于找到解决方案:https://github.com/aszidien/springboot

1 个答案:

答案 0 :(得分:0)

在Spring Boot中自定义环境的正确方法是使用EnvironmentPostProcessor,它将在ApplicationContext启动时尽早运行,并允许您管理属性源。

第1步。使用以下内容创建文件src/main/resources/META-INF/spring.factories

org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.YourEnvironmentPostProcessor

第2步。例如,使用以下内容创建文件src/main/resources/custom.properties

server.port=8081

第3步。现在创建发布处理器类

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);
    }
  }

}

现在,当您运行应用程序时,端口将更改为8081,其他任何属性都将覆盖主要属性中提供的默认值。