如何使 REST 控制器以环境为条件?
How can I make a REST controller conditional on the environment?
我们有一个用例,我们希望在除生产环境之外的每个环境中启用一组端点。我们的想法是使用 Spring 的条件注释的变体来仅在非生产环境中启用控制器,而不是为此用例实现自定义安全实现。
我们最初的尝试是通过注入指定环境类型(例如开发、测试、生产等)的动态系统 属性 来使用 @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
我们最后的尝试是编写自定义 class 扩展 Spring 的条件 class 以满足我们的需要。这目前有效,但它依赖于 Java 文件 I/O,我们希望尽可能避免这种情况。
有什么想法吗?
19 年 5 月 29 日更新
我们能够使用以下解决方案来解决我们的问题:
- 按以下方式定义自定义条件:
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");
}
}
- 在我们的控制器上使用自定义条件:
@RestController
@Conditional(NotInProductionCondition.class)
public class TestDataController
您可以使用@Profile 批注根据环境中的配置文件集来实例化 bean。
@RestController
@Profile("!prod")
class MyController {
...
}
如果您不在您的环境中使用配置文件,我想您很可能使用某种类型的环境变量来指定环境名称。您可以将其设为 spring 这样的配置文件
spring.profiles.active = ${environmentName}
我们有一个用例,我们希望在除生产环境之外的每个环境中启用一组端点。我们的想法是使用 Spring 的条件注释的变体来仅在非生产环境中启用控制器,而不是为此用例实现自定义安全实现。
我们最初的尝试是通过注入指定环境类型(例如开发、测试、生产等)的动态系统 属性 来使用 @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
我们最后的尝试是编写自定义 class 扩展 Spring 的条件 class 以满足我们的需要。这目前有效,但它依赖于 Java 文件 I/O,我们希望尽可能避免这种情况。
有什么想法吗?
19 年 5 月 29 日更新
我们能够使用以下解决方案来解决我们的问题:
- 按以下方式定义自定义条件:
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");
}
}
- 在我们的控制器上使用自定义条件:
@RestController
@Conditional(NotInProductionCondition.class)
public class TestDataController
您可以使用@Profile 批注根据环境中的配置文件集来实例化 bean。
@RestController
@Profile("!prod")
class MyController {
...
}
如果您不在您的环境中使用配置文件,我想您很可能使用某种类型的环境变量来指定环境名称。您可以将其设为 spring 这样的配置文件
spring.profiles.active = ${environmentName}