【问题标题】:How to set active profile programmatically for any environment?如何以编程方式为任何环境设置活动配置文件?
【发布时间】:2017-07-27 12:52:47
【问题描述】:

我想为任何环境设置活动配置文件主机,但找不到与环境无关的挂钩。

以下工厂将在构建应用程序上下文之前设置活动配置文件。

/META-INF/spring.factories

org.springframework.context.ApplicationContextInitializer=MyApplicationContextInitializer

MyApplicationContextInitializer.java

public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext ca) {
        ConfigurableEnvironment environment = ca.getEnvironment();
        environment.addActiveProfile("myHost");
    }
}

如果这个例子是由 JUnit 在模拟环境中执行的......

*Test.java

...
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
...

...将记录以下内容。

...
... RestControllerTests   : The following profiles are active: myHost
...

但配置文件 myHost 未激活,默认配置文件将在 JUnit 上下文中使用!

使用 VM 参数作为 Java 应用程序和 JUnit 的测试有效 ...

-Dspring.profiles.active=myHost

我使用 war 打包的 spring-boot-starter-web 应用程序,应以编程方式设置配置文件并在任何环境中使用

  • Java 应用程序
  • JUnit
  • Servlet 容器

如何以编程方式为任何环境设置配置文件?

我不想使用 VM 参数或环境变量,因为配置文件应由当前主机名设置。

【问题讨论】:

    标签: spring spring-mvc spring-boot spring-profiles spring-boot-test


    【解决方案1】:

    您不认为使用 EnvironmentPostProcessor 可以实现这一点,并且仍然对运行环境产生影响吗?我的尝试失败了。

    @Order(Ordered.LOWEST_PRECEDENCE)
    public class EnvtPostProcessor implements EnvironmentPostProcessor {
    @SuppressWarnings("deprecation")
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication application) {
        if ((env.acceptsProfiles("bar1") || env.acceptsProfiles("bar2"))
                && !(env.acceptsProfiles("foo1") || env.acceptsProfiles("foo2"))) {
            env.addActiveProfile("foo1");
        }
    }
    }
    

    注意:不要忘记在 src/main/resources/META-INF/spring.factories 中注册处理器:

    org.springframework.boot.env.EnvironmentPostProcessor=com.mygroup.myapp.EnvtPostProcessor
    

    当我只应用“bar2”活动配置文件时,在应用程序上下文初始化之前,“foo1”配置文件作为活动配置文件添加到环境中;但最终并非所有 bean 都被找到(因为它们在最初完整的活动配置文件列表用例中)。

    也许这是因为依赖关系(顺便说一下,Azure 用于 Spring Cloud 连接):我最终没有为我的 ActiveDirectoryConfigurer 找到 OAuth2UserService。

    【讨论】:

      【解决方案2】:

      我不认为一旦应用程序运行,在运行时动态(以编程方式)设置活动配置文件这样的事情,对配置文件的任何修改都不会对加载的 bean 和属性文件产生任何影响。

      但是,在运行应用程序之前,您可以配置应用程序的可用配置文件。例如:

      @SpringBootApplication
      public class DemoApplicationWithSysProperty {
      
          public static void main(String[] args) {
      
              System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, 
              PROFILE_NAME);
              SpringApplication.run(DemoApplicationWithSysProperty.class, args);
          }
      }
      

      【讨论】:

        【解决方案3】:

        经过大量谷歌搜索后的最简单答案:)

        @SpringBootApplication
        public class ExampleMain2 {
        
          public static void main(String[] args) {
              ConfigurableEnvironment environment = new StandardEnvironment();
              environment.setActiveProfiles("dev");
        
              SpringApplication sa = new SpringApplication(ExampleMain2.class);
              sa.setEnvironment(environment);
              sa.setAdditionalProfiles("remote","live");
              sa.run(args);
          }
        }
        

        【讨论】:

          【解决方案4】:

          我遇到了同样的问题,我终于通过实现 ActiveProfilesResolver 接口解决了它。

          在你的情况下,你可以这样做:

          public class MyActivateProfilesResolver implements ActiveProfilesResolver {
          
              @Override
              public String[] resolve(Class<?> testClass) {
                   // some code to find out your active profiles
                   return new String[] {"myHost"};
              }
          }
          

          然后你需要像这样将你的测试与你的解析器链接起来:

          @ActiveProfiles(resolver = MyActivateProfilesResolver.class)
          

          【讨论】:

            猜你喜欢
            • 2017-03-09
            • 2012-03-05
            • 2019-10-17
            • 2017-05-05
            • 1970-01-01
            • 2012-09-14
            • 2011-06-26
            相关资源
            最近更新 更多