如何将@Value定义为可选

问题描述 投票:0回答:5

我在 Spring bean 中有以下内容:

@Value("${myValue}")
private String value;

值已正确注入。但是,该变量需要是可选的,它作为命令行参数传入(然后使用 SimpleCommandLinePropertySource 添加到 Spring 上下文),并且此参数不会始终存在。

我尝试了以下两种方法来提供默认值:

@Value("${myValue:}")
@Value("${myValue:DEFAULT}")

但在每种情况下,即使存在实际值,冒号后的默认参数也会被注入 - 这似乎覆盖了 Spring 应该注入的内容。

指定不需要 @Value 的正确方法是什么?

谢谢

spring spring-bean
5个回答
274
投票

指定不需要 @Value 的正确方法是什么?

假设“不需要”是指

null
那么...

您已经正确地注意到,您可以在

:
字符右侧提供默认值。你的例子是
@Value("${myValue:DEFAULT}")

您不限于使用纯字符串作为默认值。您可以使用 SPEL 表达式,返回

null
的简单 SPEL 表达式为:

@Value("${myValue:#{null}}")

94
投票

如果您使用 Java 8,则可以利用其

java.util.Optional
类。 您只需按照以下方式声明变量即可:

@Value("${myValue:#{null}}")
private Optional<String> value;

然后,您可以以更好的方式检查该值是否已定义:

if (value.isPresent()) {
    // do something cool
}

希望有帮助!


8
投票

如果您想让配置属性可选,只需传递一个空字符串,如下所示:

@Value("${app.optional.value:}")

3
投票

我猜你正在使用多个上下文:属性占位符/声明?

如果是这样,这是自 2012 年以来的一个已知问题,但尚未解决,显然是由于缺乏兴趣且没有干净的解决方法。请参阅 https://github.com/spring-projects/spring-framework/issues/14623 进行讨论和解决该问题的一些方法。 http://www.michelschudel.nl/wp/2017/01/25/beware-of-multiple-spring-propertyplaceholderconfigurers-and-default-values/

以易于理解的方式进行了解释

0
投票

@alonso_50 对于 Spring Boot 3.x 和 Java 21 来说仍然是正确的。测试它/实验的游乐场:

@Component
public class Test {
    /**
     * this leads to org.springframework.beans.factory.BeanCreationException
     * (thus commented out)
     */
    // @Value("${prop1}")
    Object prop1;

    @Value("${prop2:}")
    Optional<String> prop2;

    @Value("${prop3:#{null}}")
    Optional<String> prop3;

    /**
     * output if props are NOT present
     * <pre>
     *     *BeanCreationException*
     *     Optional[]
     *     Optional.empty
     * </pre>
     * <p>
     * output if props are present ("value")
     * <pre>
     *     *BeanCreationException*
     *     Optional[value]
     *     Optional[value]
     * </pre>
     */
    @EventListener(ApplicationReadyEvent.class)
    public void test() {
        System.out.println(prop1);
        System.out.println(prop2);
        System.out.println(prop3);
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.