如何在 Spring @Value 注解中正确指定默认值?
Posted
技术标签:
【中文标题】如何在 Spring @Value 注解中正确指定默认值?【英文标题】:How to correctly specify a default value in the Spring @Value annotation? 【发布时间】: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
的属性。您应该使用后者,但您可能以错误的方式加载属性。
谢谢。如果我以错误的方式加载属性,为什么 # 会选择正确的值?
因为这是一个表达式而不是占位符。它们都以完全不同的方式进行评估。
【参考方案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】:取决于你如何加载你的属性,如果你使用类似的东西
<context:property-placeholder location="classpath*:META-INF/spring/*.properties" />
那么@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) 将被有效地忽略。
【讨论】:
这是自 2012 年以来的一个已知问题,但未修复,显然是由于缺乏兴趣和没有干净的修复方法。请参阅github.com/spring-projects/spring-framework/issues/14623 进行讨论以及一些解决方法。 michelschudel.nl/wp/2017/01/25/… 以通俗易懂的方式解释了它【参考方案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")
【讨论】:
以上是关于如何在 Spring @Value 注解中正确指定默认值?的主要内容,如果未能解决你的问题,请参考以下文章
spring boot 入门1-----如何使用@Value注解读取配置文件以及使用@ConfigrationProperties注解