我在 Spring bean 中有以下内容:
@Value("${myValue}")
private String value;
值已正确注入。但是,该变量需要是可选的,它作为命令行参数传入(然后使用 SimpleCommandLinePropertySource 添加到 Spring 上下文),并且此参数不会始终存在。
我尝试了以下两种方法来提供默认值:
@Value("${myValue:}")
@Value("${myValue:DEFAULT}")
但在每种情况下,即使存在实际值,冒号后的默认参数也会被注入 - 这似乎覆盖了 Spring 应该注入的内容。
指定不需要 @Value 的正确方法是什么?
谢谢
指定不需要 @Value 的正确方法是什么?
假设“不需要”是指
null
那么...
您已经正确地注意到,您可以在
:
字符右侧提供默认值。你的例子是@Value("${myValue:DEFAULT}")
。
您不限于使用纯字符串作为默认值。您可以使用 SPEL 表达式,返回
null
的简单 SPEL 表达式为:
@Value("${myValue:#{null}}")
如果您使用 Java 8,则可以利用其
java.util.Optional
类。
您只需按照以下方式声明变量即可:
@Value("${myValue:#{null}}")
private Optional<String> value;
然后,您可以以更好的方式检查该值是否已定义:
if (value.isPresent()) {
// do something cool
}
希望有帮助!
如果您想让配置属性可选,只需传递一个空字符串,如下所示:
@Value("${app.optional.value:}")
我猜你正在使用多个上下文:属性占位符/声明?
如果是这样,这是自 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/
以易于理解的方式进行了解释@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);
}
}