如何在任何环境中以编程方式设置活动配置文件?

7

我希望能够针对任何环境设置活动配置文件主机依赖性,并且找不到一个环境无关的挂钩。

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

/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将使用默认配置文件!

通过Java应用程序和带有VM参数的JUnit进行测试可以正常运行...

-Dspring.profiles.active=myHost

我使用打包为war的spring-boot-starter-web应用程序,并且需要在任何环境中设置和使用编程配置文件。

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

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

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

4个回答

14

经过大量搜索得出的最简单答案 :)

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

6

我曾经遇到过同样的问题,最终通过实现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)

1

我认为在应用程序运行时动态(以编程方式)设置活动配置文件并没有这样的事情,对配置文件的任何修改都不会影响已加载的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);
    }
}

0

你不觉得可以通过使用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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接