Spring @Value – 有没有一种方法可以分配一个默认的空映射?

huangapple go评论70阅读模式
英文:

Spring @Value - Is there a way to assign a default empty map?

问题

Situation

我在我的类中使用了@PropertySource和@Value,以便从属性文件中注入值到一个映射中。
用于此操作的代码如下:

@Value("#{${global.fieldsSubset}}")
private final Map<String, Set<String>> fieldsSubset = new HashMap<>();

如果找不到所需属性,我希望将映射初始化为空映射。为此,我将代码更改为:

@Value("#{${global.fieldsSubset : {}}}")
private final Map<String, Set<String>> fieldsSubset = new HashMap<>();

Problem

默认行为正常工作,当找不到属性时,映射为空。但是当属性存在时,默认值仍然保留,映射始终为空。

以下是整个类的代码:

@Configuration
@PropertySource(value = "classpath:global.properties", ignoreResourceNotFound = true)
@RefreshScope
public class FieldsSubsetsProperties {
    @Value("#{${global.fieldsSubset:{}}}")
    private final Map<String, Set<String>> fieldsSubset = new HashMap<>();

    public Map<String, Set<String>> getFieldsSubset() {
        return fieldsSubset;
    }

    public Set<String> getSubsetOfFieldsNames(String subsetName) {
        return fieldsSubset.getOrDefault(subsetName, Collections.emptySet());
    }
}

以下是属性值:

global.fieldsSubset = {\
 'channel-basic':{'id', 'number', 'name'}, \
 'channel':{'id', 'number', 'name', 'description', 'status'}\
}
英文:

Situation

I am using @PropertySource in my class along with @Value in order to inject a value to a map from a properties file.
The code for that is as follows:

@Value(&quot;#{${global.fieldsSubset}}&quot;)
private final Map&lt;String, Set&lt;String&gt;&gt; fieldsSubset = new HashMap&lt;&gt;();

In case the required property isn't found I'd like to initialize the map as an empty map. For that I changed the code to:

@Value(&quot;#{${global.fieldsSubset : {:}}}&quot;)
private final Map&lt;String, Set&lt;String&gt;&gt; fieldsSubset = new HashMap&lt;&gt;();

Problem

The default behavior works fine and the map is empty when the property isn't found, but when the property is present the default value still remains and the map is always empty.

Here is the whole class:

@Configuration
@PropertySource(value = &quot;classpath:global.properties&quot;, ignoreResourceNotFound = true)
@RefreshScope
public class FieldsSubsetsProperties {
    @Value(&quot;#{${global.fieldsSubset:{:}}}&quot;)
    private final Map&lt;String, Set&lt;String&gt;&gt; fieldsSubset = new HashMap&lt;&gt;();

    public Map&lt;String, Set&lt;String&gt;&gt; getFieldsSubset() {
        return fieldsSubset;
    }

    public Set&lt;String&gt; getSubsetOfFieldsNames(String subsetName) {
        return fieldsSubset.getOrDefault(subsetName, 
     Collections.emptySet());
    }
}

Here is the property value:

global.fieldsSubset = {\
 &#39;channel-basic&#39;:{&#39;id&#39;, &#39;number&#39;, &#39;name&#39;}, \
 &#39;channel&#39;:{&#39;id&#39;, &#39;number&#39;, &#39;name&#39;, &#39;description&#39;, &#39;status&#39;}\
}

答案1

得分: 4

@Value("#{${global.fieldsSubset:{T(java.util.Collections).emptyMap()}}}")
private final Map<String, Set<String>> fieldsSubset = new HashMap<>();
英文:

Try this:

@Value(&quot;#{${global.fieldsSubset:{T(java.util.Collections).emptyMap()}}}&quot;)
private final Map&lt;String, Set&lt;String&gt;&gt; fieldsSubset = new HashMap&lt;&gt;();

答案2

得分: 1

尝试使用 Elvis 运算符

@Value("#{${global.fieldsSubset} ?: { : }}")
private final Map<String, Set<String>> fieldsSubset = new HashMap<>();
英文:

Try using the Elvis operator

@Value(&quot;#{${global.fieldsSubset} ?: { : }}&quot;)
private final Map&lt;String, Set&lt;String&gt;&gt; fieldsSubset = new HashMap&lt;&gt;();

答案3

得分: 0

我认为您有2个错误:

  1. 在字段声明中,final 是错误的。字段必须是非 final 的,这样 Spring 才能在构建 bean 实例后设置其值。
  2. JSON 格式错误。Set 映射到 JSON 列表,因此 JSON 应该是例如 &#39;channel&#39;:[&#39;id&#39;, &#39;number&#39;, &#39;name&#39;, &#39;description&#39;, &#39;status&#39;],这意味着您应该使用括号而不是大括号来表示映射的值。
英文:

I think you have 2 errors:

  1. In the declaration of the field, the final is wrong. The field must be non-final, so that Spring can set its value after constructing the bean instance
  2. The JSON is wrong. A Set is mapped to a JSON list, so the JSON should be i.e. &#39;channel&#39;:[&#39;id&#39;, &#39;number&#39;, &#39;name&#39;, &#39;description&#39;, &#39;status&#39;], meaning you should use brackets instead of braces for the values of the map

答案4

得分: 0

@Value("#{systemProperties['some.key'] ?: 'my default system property value'}")
private String spelWithDefaultValue;

更多关于默认值的信息:https://www.baeldung.com/spring-value-defaults

英文:
@Value(&quot;#{systemProperties[&#39;some.key&#39;] ?: &#39;my default system property value&#39;}&quot;)
private String spelWithDefaultValue;

More info about default values: https://www.baeldung.com/spring-value-defaults

huangapple
  • 本文由 发表于 2020年7月30日 22:36:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/63175480.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定