ChatGPT解决这个技术问题 Extra ChatGPT

我可以将 null 设置为 Spring 中 @Value 的默认值吗?

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

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

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


C
Community

这真的很旧,但你现在可以使用 Spring EL,例如

@Value("${stuff.value:#{null}}")

请参阅this question


应该选择这个作为问题的答案。
K
Kirill Ch

感谢@vorburger:

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

将字符串值设置为 null 而无需任何其他配置。


在 2019 年最新版本的 spring-boot 中工作:2.1.7.RELEASE ... start.spring.io
也适用于 Spring Boot 2.5.6
也适用于 Spring boot 2.6.2!
n
nosebrain

您必须设置 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;

请注意:上下文命名空间目前不支持空值。你不能使用

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

使用 Spring 3.1.1 测试


与此等效的 Java 配置是什么?
stackoverflow.com/questions/9347929/… 提到使用 ${some.param:#{null}},这对我有用而无需设置 nullValue,似乎这是默认设置? (在 Spring Boot 应用程序中。)
vorburger 和 stackoverflow.com/questions/16735141/… 中建议的 SPEL ${stuff.value:#{null}} 的简单使用功能
ben3000 和 JRichardsz 的答案似乎需要更少的配置。
有一种更新的方法可以将 null 设置为默认值,请在此处查看最新的答案
A
Adam Gent

我给予@nosebrain 信用,因为我不知道“空值”,但我更愿意完全避免使用空值,特别是因为它难以在属性文件中表示 null

但是这里有一个替代方法,它使用 null 而没有 null-value,因此它可以与任何属性占位符一起使用。

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 成为逗号分隔值,或者 Enum 切换更容易。它也更容易进行单元测试:)

编辑:根据您对使用枚举的评论以及我对不使用 null 的看法。

@Component
public class MyObject {

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

    public enum Crap {
        NOTSET,
        BLAH;
    }
}

以上对我来说很好。你避免空值。如果您的属性文件想要明确设置他们不想处理它,那么您可以这样做(但您甚至不必指定它,因为它默认为 NOTSET)。

crap=NOTSET

null 非常糟糕,与 NOTSET 不同。这意味着弹簧或单元测试没有设置它,这就是恕我直言的原因。我仍然可能会使用 setter 表示法(上一个示例),因为它更容易进行单元测试(私有变量很难在单元测试中设置)。


String 值就是一个例子,我真的需要这个 Enum 值,其中一个空的 String 只会导致转换错误。使用@null,您可以将 null 作为“无枚举集”,这正是我所需要的。
我不推荐 null 而是推荐一些表示未设置的枚举的更多原因。
这需要将 Enum.NOTSET 放入所有属性文件(> 30)中,这似乎需要做很多工作而几乎没有任何好处......
我没有尝试过,但理论上 @Value("${stuff.value:NOTSET}") 行不通?
是的,这是一个很好的解决方案。不幸的是,我无法更改枚举(dep),所以我必须使用 null。否则你是对的,NOTSET 会起作用。
y
ylev

如果您需要注入一个空的(0 长度)“”字符串作为 @Value 默认值 - 使用 SPEL(弹簧表达式语言),如下所示:

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

#{''} 只是为您提供一个空字符串作为注入@Value 的默认值。

由 yl


最初的 @Value("${stuff.value:}") private String value; 完全一样,并且是首选的方式。无论如何,您的回复并没有回答问题。