【问题标题】:How to correctly specify a default value in the Spring @Value annotation?如何在 Spring @Value 注解中正确指定默认值?
【发布时间】:2015-01-11 01:17:38
【问题描述】:

最初,我有以下规格:

@Value("#{props.isFPL}")
private boolean isFPL=false;

这可以正常从属性文件中获取值:

isFPL = true

但是,以下带有默认值的表达式会导致错误:

@Value("#{props.isFPL:false}")
private boolean isFPL=false;

表达式解析失败;嵌套异常是 org.springframework.expression.spel.SpelParseException: EL1041E:(pos 28): 解析有效表达式后,表达式中还有更多数据:'colon(:)'

我也尝试使用 $ 而不是 #。

@Value("${props.isFPL:true}")
private boolean isFPL=false;

然后注释中的默认值可以正常工作,但我没有从属性文件中得到正确的值:

【问题讨论】:

  • #{} 是一个表达式,${} 是一个值的占位符。您使用的第一个表达式将在名为 props 的 bean 上调用方法/属性,带有占位符的表达式将尝试在 Environment 中找到名为 props.isFPL 的属性。您应该使用后者,但您可能以错误的方式加载属性。
  • 谢谢。如果我以错误的方式加载属性,为什么 #{} 会选择正确的值?
  • 因为这是一个表达式而不是占位符。它们都以完全不同的方式进行评估。

标签: java spring properties annotations


【解决方案1】:

尝试使用$,如下所示:

@Value("${props.isFPL:true}")
private boolean isFPL=false;

还要确保将ignore-resource-no-found 设置为true,这样如果缺少属性文件,将采用默认 值。

如果使用基于 XML 的配置,请将以下内容放在上下文文件中:

<context:property-placeholder ignore-resource-not-found="true"/>

如果使用 Java 配置:

 @Bean
 public static PropertySourcesPlaceholderConfigurer   propertySourcesPlaceholderConfigurer() {
     PropertySourcesPlaceholderConfigurer p =  new PropertySourcesPlaceholderConfigurer();
     p.setIgnoreResourceNotFound(true);

    return p;
 }

【讨论】:

  • 我的 $ 问题不是忽略默认值。问题是属性文件中的值被忽略了
  • 你是如何加载属性文件的?
【解决方案2】:

取决于你如何加载你的属性,如果你使用类似的东西

&lt;context:property-placeholder location="classpath*:META-INF/spring/*.properties" /&gt;

那么@Value 应该是这样的

@Value("${isFPL:true}")

【讨论】:

    【解决方案3】:

    您的 Spring 应用程序上下文文件是否包含多个 propertyPlaceholder bean,如下所示:

    <context:property-placeholder ignore-resource-not-found="true" ignore-unresolvable="true" location="classpath*:/*.local.properties" />
    <context:property-placeholder location="classpath:/config.properties" />
    

    如果是这样,那么属性查找:props.isFPL 将只针对第一个属性文件 (.local.properties),如果没有找到属性,则默认值 (true) 将生效,并且此属性的第二个属性文件 (config.properties) 将被有效地忽略。

    【讨论】:

    【解决方案4】:

    对于int 类型变量:

    @Value("${my.int.config: #{100}}")
    int myIntConfig;
    

    注意:冒号之前没有空格,而冒号之后有多余的空格。

    【讨论】:

    • 我认为不需要额外的空格(冒号后)。
    • 似乎是旧答案。我能够像任何其他值一样映射 int 值。 @Value("${my.int.config:100}")
    【解决方案5】:

    对于字符串,您可以像这样默认为 null:

    public UrlTester(@Value("${testUrl:}") String url) {
        this.url = url;
    }
    

    【讨论】:

    • 从维护的角度来看,我宁愿看到@Value("${testUrl:#{null}}")
    • 这似乎是错误的。对于 String ${var:} 默认为空 String ""
    【解决方案6】:

    这种定义默认值的方式只有当我们在@Value 注解中写“value=...”时才有效。例如

    不起作用 : @Value("${testUrl:some-url}" // 无论你在配置文件中做什么,这总是会设置“some-url”。

    Works : @Value(value = "${testUrl:some-url}" // 仅当配置文件中缺少 testUrl 属性时才会设置“some-url”。

    【讨论】:

      【解决方案7】:

      您问题的确切答案取决于参数的类型

      对于“字符串”参数,您的示例代码可以正常工作:

      @Value("#{props.string.fpl:test}")
      private String fpl = "test";
      

      对于其他类型(如您问题中的布尔值),它应该这样写:

      @Value("${props.boolean.isFPL:#{false}}")
      private boolean isFPL = false;
      

      或者对于“整数”:

      @Value("${props.integer.fpl:#{20}}")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-25
        • 1970-01-01
        • 1970-01-01
        • 2017-08-31
        • 2018-07-14
        • 2015-08-07
        • 1970-01-01
        相关资源
        最近更新 更多