在java.util.Set变量的Spring @Value中将默认值设置为null

时间:2017-01-25 21:20:44

标签: java spring spring-el

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

所以,这可行(varStr为null):

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

虽然这不是(varSet现在包含一个元素"#{NULL}"):

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

问题是如何使用Set变量使其工作,因此默认情况下它将设置为null。

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

您可以尝试将@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往往容易出错,并且通常不会传达任何比空集合更多的信息。您的情况可能会有所不同 - 这只是一般性建议。

BTW - Sets.newHashSet(...)来自Google's Guava library。强烈推荐。

答案 1 :(得分: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。

答案 2 :(得分:0)

除非您能找到一个优雅的解决方案来解决这个问题,否则您可以将该属性作为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(",")));
    }
}