【问题标题】:Set default value to null in Spring @Value on a java.util.Set variable在 java.util.Set 变量上的 Spring @Value 中将默认值设置为 null
【发布时间】:2017-01-25 21:20:43
【问题描述】:

使用 SpEL 的 Spring @Value 注释有一个有趣的问题。设置 null 的默认值适用于 String 变量。但是,对于 Set 变量,它不会。

所以,这行得通(varStr 为空):

@Value("${var.string:#{NULL}}")
private String varStr;

虽然没有(varSet 现在包含一个带有“#{NULL}”的元素):

@Value("#{'${var.set:#{NULL}}'.split(',')}")
private Set<String> varSet;

问题是如何使用 Set 变量进行这项工作,以便默认情况下将其设置为 null。

我们将不胜感激。

【问题讨论】:

  • 想要将这样的注入依赖默认设置为null,这似乎非常奇怪。
  • 虽然我同意这是一种非常奇怪的愿望,但我想知道你为什么要把这个表达式放在引号中,即'${var.set:#{NULL}}'
  • 我个人从不使用Field注入,一直使用Constructor注入。通过这种方式,如果您确实需要,您可以控制在构造函数中将字段值设置为 null
  • 外部 var.set 属性是可选属性(并不总是设置)。因此,如果未定义,我们需要将 varSet 对象默认为 null。只是业务需求。

标签: java spring spring-el


【解决方案1】:

您可以尝试将@Value 注入数组而不是Set。然后在 @PostConstruct init 块中将其转换为所需的 Set 实例。当不存在此类属性时,Spring 似乎正在注入一个空数组(非空)(注意@Value 字符串中的空默认值)。如果确实存在,则默认以逗号分隔。

像这样:

@Value("${some.prop:}")
private String[] propsArr;
private Set<String> props;

@PostConstruct
private void init() throws Exception {
    props = (propsArr.length == 0) ? null : Sets.newHashSet(propsArr);
}

我只是提出另一个建议。我建议您根本不要使用null,而是使用一个空的 Set 来代替。 Null 往往容易出错,并且通常不会传达比空集合更多的信息。您的情况可能会有所不同 - 这只是一般性建议。

顺便说一句-Sets.newHashSet(...) 的电话来自Google's Guava library。强烈推荐。

【讨论】:

  • 谢谢佩多罗。正在尝试使用 SpEL 完成这一切,从而避免 @PostConstruct 和额外的编码。尽管如此,还是选择了你的解决方案,它奏效了。
【解决方案2】:

您可以创建一个 PropertySourcesPlaceholderConfigurer。该 bean 将拦截属性源值并允许您对其进行配置。

@Configuration
@ComponentScan
class ApplicationConfig {

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
  PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
  c.setNullValue("");
  return c;
}

参考:http://blog.codeleak.pl/2015/09/placeholders-support-in-value.html

这会将空字符串默认为 null。

【讨论】:

  • 对不起,对我来说似乎没有什么不同。
【解决方案3】:

除非你能找到一个优雅的解决方案来解决这个问题,否则你可以将属性作为 String 注入到你的构造函数中,然后自己注入 Split() 或默认为 null

class Foo {

    private Set<String> varSet;

    public Foo(@Value("${var.string:#{NULL}}") String varString) {
        varSet = (varString == null) ? null : new HashSet<>(Arrays.asList(varString.split(",")));
    }
}

【讨论】:

  • 是的,可能必须解决获取字符串然后应用拆分。
猜你喜欢
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 2019-05-15
  • 2016-12-28
相关资源
最近更新 更多