Spring @ConditionalOnProperty具有Value =“ value1”或“ value2”

MLS*_*MLS 7 java spring javabeans spring-boot

我正在寻找configurationOnProperty可以指定考虑多个值的用法,如下所示

例如: @ConditionalOnProperty(value = "test.configname", havingValue = "value1" or "value2")

要么

我想知道是否可以指定confiugrationOnProperty条件havingValue != "value3"

例如: @ConditionalOnProperty(value = "test.configname", havingValue != "value3")

请让我知道是否有一种方法可以实现上述任何一项spring boot配置。

Ali*_*ien 11

注释@ConditionalOnProperty@ConditionalOnExpression两者都没有java.lang.annotation.Repeatable注释,因此您无法仅添加多个注释来检查多个属性。

以下语法已经过测试并有效:

两个属性的解决方案

@ConditionalOnExpression("${properties.first.property.enable:true} && ${properties.second.property.startServer:false}")
Run Code Online (Sandbox Code Playgroud)

请注意以下事项:

  • 表达式语言语句中需要使用冒号表示属性的默认值
  • 每个属性都在一个单独的表达式语言块 ${}
  • && 运算符在 SpEL 块之外使用

它允许具有不同值的多个属性并且可以扩展到多个属性。

如果要检查多于 2 个值并仍保持可读性,可以在要评估的不同条件之间使用连接运算符:

超过 2 个属性的解决方案

@ConditionalOnExpression("${properties.first.property.enable:true} " +
        "&& ${properties.second.property.enable:true} " +
        "&& ${properties.third.property.enable:true}")
Run Code Online (Sandbox Code Playgroud)

缺点是您不能像使用注释一样使用 matchIfMissing 参数,@ConditionalOnProperty因此您必须确保所有配置文件/环境的.propertiesYAML文件中都存在这些属性,或者仅依赖默认值价值

取自此处Spring Boot SpEL ConditionalOnExpression 检查多个属性


And*_*son 7

Spring Boot提供AnyNestedCondition了一个已创建的条件,该条件将在任何嵌套条件匹配时匹配。当所有嵌套条件或没有嵌套条件分别匹配时,它还提供AllNestedConditionsNoneNestedConditions进行匹配。

对于您要匹配value1或的值的特定情况,value2您可以创建AnyNestedCondition如下所示的代码:

class ConfigNameCondition extends AnyNestedCondition {

    public ConfigNameCondition() {
        super(ConfigurationPhase.PARSE_CONFIGURATION);
    }

    @ConditionalOnProperty(name = "test.configname", value = "value1")
    static class Value1Condition {

    }

    @ConditionalOnProperty(name = "test.configname", value = "value2")
    static class Value2Condition {

    }

}
Run Code Online (Sandbox Code Playgroud)

然后将其与一起使用@Conditional,例如:

@Bean
@Conditional(ConfigNameCondition.class)
public SomeBean someBean() {
    return new SomeBean();
}
Run Code Online (Sandbox Code Playgroud)

如嵌套条件注释的javadoc中所示(链接到上面),嵌套条件可以是任何类型。在这种特殊情况下,它们不必都具有相同的类型。

  • 看起来很糟糕。您有票可以使 @ConditionalOnProperty 可重复吗? (3认同)
  • 我上面链接到的问题尚未被拒绝,如果您阅读它,您会发现还需要对 Spring 框架进行更改。也许您不想发表一系列贬损性言论,而是想做一些建设性的事情并贡献一些拉取请求? (3认同)

Meh*_*lik 6

我正在寻找configurationOnProperty可以指定考虑多个值的用法

您可以使用Condition接口Spring 4.0

该接口有一个matches(...)您可以使用的方法。

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class TestCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String testValue = (context.getEnvironment().getProperty("test.configname");
        return "value1".equalsIgnoreCase("testValue") || "value2".equalsIgnoreCase("testValue");
    }

}
Run Code Online (Sandbox Code Playgroud)

然后TestCondition在你的内部使用@Configuration如下:

@Configuration
public class TestConfig {

      @Conditional(value=TestCondition .class)
      public MyBean getTestConfigBean() {
          //TODO YOUR CODE;
      }

}
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以指定 configurationOnProperty 条件为havingValue != "value3"

public class TestCondition2 implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String testValue = (context.getEnvironment().getProperty("test.configname");
        return ! "value3".equalsIgnoreCase("testValue");
    }

}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

@Configuration
public class TestConfig {

      @Conditional(value=TestCondition2 .class)
      public MyBean getTestConfigBean() {
          //TODO YOUR CODE;
      }

}
Run Code Online (Sandbox Code Playgroud)