I have a properties file that contains a map with keys that each have multiple values, like below
//properties.yml
myMap:
key1: value1, value2
key2: value1, value2, value3
It is fairly easy to read myMap
using a Spring properties class as follows:
@Configuration
@ConfigurationProperties
public class MyConfiguration {
private Map<String, List<String>> myMap;
public Map<String, List<String>> getMyMap() {
return myMap;
}
public void setMyMap(Map<String, List<String>> myMap) {
this.myMap = myMap;
}
}
However this feels like a lot of code for a simple task. I was wondering if there is a way to achieve the same thing using Spring's @Value
annotation? I've tried to get it to work without success, trying things like
@Value("${myMap}")
private Map<String, List<String>> myMap;
I think maybe it requires SPEL but I'm not sure how
One of the most important annotations in spring is @Value annotation which is used to assign default values to variables and method arguments. We can read spring environment variables as well as system variables using @Value annotation. It also supports Spring Expression Language (SpEL).
3. How to Inject a Map From a YAML File. Spring Boot has taken data externalization to the next level by providing a handy annotation called @ConfigurationProperties. This annotation is introduced to easily inject external properties from configuration files directly into Java objects.
@Value is a Java annotation that is used at the field or method/constructor parameter level and it indicates a default value for the affected argument. It is commonly used for injecting values into configuration variables - which we will show and explain in the next part of the article.
@ConfigurationProperties provides validation of properties using the JSR-303 format. This allows all sorts of neat things.
To Inject Map using @Value you can do (but maybe you need to modify your YAML):
@Value("#{${myMap}}")
private Map<String, List<String>> myMap;
However, It is encouraged to use @ConfigurationProperties instead of @Value (especially if you use YAML format, Spring boot uses SnakeYAML to parse YAML files)
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties
You don't need a setter when loading to the map:
@ConfigurationProperties
public class MapProperties {
private Map<String, List<String>> myMap = new HashMap<>();
public Map<String, List<String>> getMyMap() {
return this.myMap;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With