如何使REST控制器取决于环境?

时间:2019-05-28 19:33:50

标签: spring rest maven spring-boot spring-config

我们有一个用例,我们希望在除生产环境之外的所有环境中启用一组端点。我们的想法不是使用此用例实现自定义安全性实现,而是使用Spring条件注释的一种变体,以仅在非生产环境中启用控制器。

我们最初的尝试是通过注入指定环境类型的动态系统属性(例如dev,test,prod等)来使用@ConditionalOnExpression,并将该属性与正则表达式进行匹配,但我们尚未能够使SpEL表达式以适合我们需求的方式正确解析。

@RestController
@ConditionalOnExpression("${property.name} matches ^((?!prod).)*$")
public class TestDataController

我们也考虑过使用@ConditionalOnProperty,但是似乎没有办法允许此属性接受多个有效值。

@RestController
@ConditionalOnProperty(
        value = "property.name",
        havingValue = "value1" or "value2",
        matchIfMissing = true)
public class TestDataController

我们最后的尝试是编写一个自定义类,以扩展Spring的Conditional类以适应我们的需求。目前可以使用,但是它依赖Java文件I / O,我们希望尽可能避免这种情况。

有什么想法吗?

更新19 May 19

我们能够使用以下解决方案来解决我们的问题:

  1. 通过以下方式定义自定义条件:
public class NotInProductionCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        final String env = context.getEnvironment().getProperty("property.name");
        if (env == null || env.isEmpty()) {
            return true;
        }
        return !env.contains("prod");
    }
}
  1. 在我们的控制器上使用自定义条件:
@RestController
@Conditional(NotInProductionCondition.class)
public class TestDataController

1 个答案:

答案 0 :(得分:4)

您可以根据环境中设置的配置文件,使用@Profile批注实例化bean。

@RestController
@Profile("!prod")
class MyController {
  ...
}

我想,如果您在环境中不使用配置文件,则很可能使用某种类型的环境变量来指定环境名称。您可以像这样将其制成弹簧轮廓

spring.profiles.active = ${environmentName}