在Spring中,我能否将null设置为@Value的默认值?

165

我目前正在使用Spring 3.1.x中的@Value注释,像这样:

@Value("${stuff.value:}")
private String value;

如果属性不存在,这会将一个空字符串放入变量中。我希望默认值为null而不是空字符串。当然,我也想避免在未设置属性stuff.value时出现错误。

5个回答

340

这个确实有点老了,但是现在你可以使用Spring EL,例如:

@Value("${stuff.value:#{null}}")
private String stuffValue;

请查看此问题


3
这应该被选为问题的答案。 - Dáve

90

感谢 @vorburger 提供的帮助:

@Value("${email.protocol:#{null}}")
String protocol;

不做任何其他配置,将字符串值设置为null


3
我曾经在Spring Boot的2019年最新版本2.1.7.RELEASE中工作过... https://start.spring.io/ - JRichardsz
同样适用于Spring Boot 2.5.6。 - Esteban
还适用于Spring Boot 2.6.2! - Day Break

80

你必须设置PropertyPlaceholderConfigurer的nullValue。在我的例子中,我使用字符串@null,但你也可以使用空字符串作为nullValue。

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <!-- config the location(s) of the properties file(s) here -->
    <property name="nullValue" value="@null" />
</bean>

现在,您可以使用字符串@null来表示null值。

@Value("${stuff.value:@null}")
private String value;

请注意:目前情境名称空间不支持null值。您无法使用

<context:property-placeholder null-value="@null" ... />

使用了 Spring 3.1.1 进行测试


2
这个的Java配置等价物是什么? - Kumar Sambhav
37
在Spring Boot应用程序中,https://dev59.com/C2ox5IYBdhLWcg3wOx1i提到可以使用${some.param:#{null}},这对我起作用了,而且无需设置nullValue,似乎这是默认的行为。 - vorburger
7
建议使用 Vorburger 提出的 SPEL 功能 ${stuff.value:#{null}} 来简单使用,详见以下链接: https://dev59.com/FWQn5IYBdhLWcg3wj33z - csf
似乎对于ben3000和JRichardsz的答案,需要的配置要少得多。 - Jeff
有一种更新的方法可以将 null 设置为默认值,请参见此处更新的答案。 - Dáve

2

我要感谢 @nosebrain,因为在他之前我不知道“null-value”的存在。但是个人更喜欢完全避免使用 null 值,特别是因为在属性文件中很难表示 null

以下是一个替代方案,可以在没有 null-value 的情况下使用 null,以便与任何属性占位符一起使用。

public class MyObject {

   private String value;

   @Value("${stuff.value:@null}")
   public void setValue(String value) {
      if ("@null".equals(value)) this.value = null;
      else this.value = value;
   }
}

个人而言,我更喜欢我的方式,因为也许以后您想让stuff.value 成为一个逗号分隔的值或者枚举开关更容易。这也更容易进行单元测试 :)

编辑:根据您对使用枚举的评论和我不使用 null 的观点。

@Component
public class MyObject {

    @Value("${crap:NOTSET}")
    private Crap crap;

    public enum Crap {
        NOTSET,
        BLAH;
    }
}

对我来说,以上内容很好。你避免了空值。如果你的属性文件想要显式地设置它们不想处理它,那么你可以这样做(但你甚至不需要指定这个,因为它将默认为NOTSET)。

crap=NOTSET

null非常糟糕,与NOTSET不同。这意味着Spring或单元测试没有设置它,这就是为什么我认为有所区别的原因。我仍然可能会使用setter符号(前面的示例),因为它更容易进行单元测试(在单元测试中很难设置私有变量)。


字符串值只是一个例子,我真正需要的是枚举值,在其中空字符串会导致转换错误。使用 @null,您可以将 null 作为“无枚举集”来使用,这正是我所需要的。 - Kevin Schmidt
更加理由是我不会推荐使用 null,而是一些代表未设置的枚举。 - Adam Gent
3
这需要在所有属性文件(>30)中加入 Enum.NOTSET,看起来需要花费很多工作量,但几乎没有任何好处... - Kevin Schmidt
我没有尝试过,但理论上 @Value("${stuff.value:NOTSET}") 不会起作用吗? - Adam Gent
是的,这是一个好的解决方案。不幸的是我不能改变枚举(dep),所以我只能使用null。否则你是对的,NOTSET会起作用。 - Kevin Schmidt
赋予一个整数值怎么样? @Value("${datasource.connections:5}") private Integer connections;这样可以吗? - yousafsajjad

0

如果您需要将一个空的(长度为0)""字符串注入为@Value默认值 - 可以使用SPEL(Spring表达式语言),如下所示:

@Value("${index.suffix:#{''}}") 
private String indexSuffix;

#{''} 只会得到一个空字符串,作为注入 @Value 的默认值。

作者:yl


1
初始的 @Value("${stuff.value:}") private String value; 做的事情完全相同,也是首选的方法。 无论如何,你的回复并没有回答问题。 - Andrew T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接