How to inject a Map using the @Value Spring Annotation?
Solution 1
I believe Spring Boot supports loading properties maps out of the box with @ConfigurationProperties annotation.
According that docs you can load properties:
my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com
into bean like this:
@ConfigurationProperties(prefix="my")
public class Config {
private List<String> servers = new ArrayList<String>();
public List<String> getServers() {
return this.servers;
}
}
I used @ConfigurationProperties feature before, but without loading into map. You need to use @EnableConfigurationProperties annotation to enable this feature.
Cool stuff about this feature is that you can validate your properties.
Solution 2
You can inject values into a Map from the properties file using the @Value
annotation like this.
The property in the properties file.
propertyname={key1:'value1',key2:'value2',....}
In your code.
@Value("#{${propertyname}}") private Map<String,String> propertyname;
Note the hashtag as part of the annotation.
Solution 3
You can inject .properties
as a map in your class using @Resource
annotation.
If you are working with XML based configuration
, then add below bean in your spring configuration file:
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:your.properties"/>
</bean>
For, Annotation based:
@Bean(name = "myProperties")
public static PropertiesFactoryBean mapper() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource(
"your.properties"));
return bean;
}
Then you can pick them up in your application as a Map:
@Resource(name = "myProperties")
private Map<String, String> myProperties;
Solution 4
I had a simple code for Spring Cloud Config
like this:
In application.properties
spring.data.mongodb.db1=mongodb://[email protected]
spring.data.mongodb.db2=mongodb://[email protected]
read
@Bean(name = "mongoConfig")
@ConfigurationProperties(prefix = "spring.data.mongodb")
public Map<String, Map<String, String>> mongoConfig() {
return new HashMap();
}
use
@Autowired
@Qualifier(value = "mongoConfig")
private Map<String, String> mongoConfig;
@Bean(name = "mongoTemplates")
public HashMap<String, MongoTemplate> mongoTemplateMap() throws UnknownHostException {
HashMap<String, MongoTemplate> mongoTemplates = new HashMap<>();
for (Map.Entry<String, String>> entry : mongoConfig.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
MongoTemplate template = new MongoTemplate(new SimpleMongoDbFactory(new MongoClientURI(v)));
mongoTemplates.put(k, template);
}
return mongoTemplates;
}
Solution 5
To get this working with YAML, do this:
property-name: '{
key1: "value1",
key2: "value2"
}'
yathirigan
Solution Architect currently working with Microservices, APIs, Cloud Native Architecture for PCF PaaS
Updated on July 08, 2022Comments
-
yathirigan almost 2 years
How can I inject values into a Map from the properties file using the @Value annotation in Spring?
My Spring Java class is and I tried using the $, but got the following error message:
Could not autowire field: private java.util.Map Test.standard; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'com.test.standard' in string value "${com.test.standard}"
@ConfigurationProperty("com.hello.foo") public class Test { @Value("${com.test.standard}") private Map<String,Pattern> standard = new LinkedHashMap<String,Pattern> private String enabled; }
I have the following properties in a .properties file
com.test.standard.name1=Pattern1 com.test.standard.name2=Pattern2 com.test.standard.name3=Pattern3 com.hello.foo.enabled=true
-
yathirigan almost 9 yearsyes but, my problem is.. The Test class has its own @ConfigurationProperties prefix. So i want to use a diff prefix for this member variable alone . how can i do that ?
-
yathirigan almost 9 yearsWe have used Spring Cloud Config server to provide the configurations, hence class path approach might not work. And we don't use XMLs
-
luboskrnac almost 9 yearshmm, I missed that. So I would create separate two beans with @ConfiguraitonProperties annotation and autowire them into test class.
-
dustin.schultz about 8 yearsvalues must be quotes, else I get a
SpelEvaluationException
-
petertc over 7 yearsHow to set default value if the property is absent to prevent exception occurred?
-
partTimeNinja over 7 yearsIf you want to use strings with whitespaces ( e.g USB Camera 0xfd120000046d0819 ) as keys, use single quotes as for values.
-
xenoterracide over 7 yearsmay have worked for the OP, but question didn't specify boot, and this problem doesn't work for general Spring, without boot.
-
xenoterracide over 7 yearswhat if there's a
:
in the key? -
PeterK over 6 yearsAlso seems to do type conversions e.g.:
@Value("#{${double.map}}") final Map<String, Double> doubleMap
-
emanuel07 almost 6 yearsHow to set default value ?
-
Mukul Anand almost 6 yearsthe question is how to inject to a map using @Value annotation, but you are telling all sort of things rather than giving the answer to the question. Alternatives are okay but please stick to the answer as well
-
Mukul Anand almost 6 yearsHow to specify the same in a yml file
-
joemat over 5 years@MukulAnand in yaml it looks like this
propertyname : > { key1:'value', key2:'value' }
Sorry, I'm not able to format the linebreaks correct -
Mike D3ViD Tyson over 5 years"Note the hashtag as part of the annotation..."
-
David M. Karr about 5 yearsIs it actually possible to do this? I'm trying to use SPeL in code to do the same thing, but it just says "No converter found capable of converting from type [java.lang.String] to type [java.util.Map<java.lang.String, java.lang.String>]".
-
Andrey M. Stepanov about 5 yearspattern "propertyname: {key1:'value1',key2:'value2',....}" does not work when injecting map from .yaml : java.lang.IllegalArgumentException: Could not resolve placeholder
-
rslj almost 5 yearsI think your definition for the bean mongoConfig is incorrect. The method should be defined like this. public Map<String, String> mongoConfig() { return new HashMap(); }
-
Woland over 4 yearsWhat if value has SpEL expression with
'
? :( -
g00glen00b over 4 yearsBe aware, this isn't the same as using
propertyname.key1=...
andpropertyname.key2=...
. In stead, it uses a single property calledpropertyname
. The equivalent in YAML is to treat it as a string as well and by wrapping it in quotes, such as:"{key1:'value1',key2:'value2',....}"
. For more infor, check this question. -
Agoston Horvath over 4 yearsthis is probably the most elegant way if you simply want to inject a map from application.yml
-
PAA about 4 years@MikeD3ViDTyson - Could you please guide me here: stackoverflow.com/questions/60899860/… ?
-
PAA about 4 years@Arpit - Could you please guide me here : stackoverflow.com/questions/60899860/…?
-
Brunke almost 4 yearsThank you for answering the actual question that was asked!!! The chosen answer may have been what the OP wanted to know. But, this answer actually answered the question THAT WAS ASKED!! Huge help!!! Thanks!
-
Francois Marot over 3 yearsyou can set the default value like this for an empty map: @Value("#{${tomcat.oleaconfig:{:}}}")
-
Artanis Zeratul about 3 yearshow about Map<String, List<String>>? Is this possible?
-
Simon Logic over 2 yearshow to make proper fallback to empty map if property is not found? otherwise context won't be initialized.