Reputation: 424973
How does one populate a map of values using the @Values
annotation, without defining anything in applicationContext.xml or any other XML file.
I am using spring boot, which doesn't have any XML files, and nor do I want any XML files, so please don't tell me to declare any property reader beans in XML etc.
Also, this is a properties injection question - please don't suggest using a database to store the data - that's not an answer, and not possible for my situation anyway.
Also, I can't use YAML either (due to deployment/operational requirements).
I have tried declaring this injection:
@Value("${myprop}")
Map<Integer, String> map;
And this one
@Value("${myprop.*}")
Map<Integer, String> map;
with these entries application.properties
:
myprop.1=One
myprop.2=Two
myprop.3=Three
and then tried
myprop[1]=One
myprop[2]=Two
myprop[3]=Three
But no good - just explodes with
Could not autowire field: ... Could not resolve placeholder 'myprop'
I have found a work-around with an injected String[]
specified as key1:value1,key2:value2,...
that I then parse in code, but I'd prefer to not do that because a) it's more code, and b) the list is going to be quite long, and all pairs on one line is going to be hard to read and maintain.
Is there a way to automatically build a map from several properties?
I don't care what the property names are, what the field type or the annotation is; I'm just trying to inject one key/value pair per property.
Upvotes: 3
Views: 3105
Reputation: 1396
Hello for people serach a simply solution to this problem. 😄
put the sequent line to your application.properties:
myprop = "{1:'One',2:'Two',3:'Three'}"
then in your Spring application put the line:
@Value("#{${myprop}}")
Map<Integer, String> map;
Upvotes: 0
Reputation: 52368
Not sure if this applies to your scenario entirely (you have there a Map<Integer, String>
but in the end you say you just need a key-value pair in a Map), but maybe it could give you some more ideas:
@Configuration
class where the .properties file is loaded as a java.util.Properties
object:@Configuration
public class Config {
@Bean(name = "mapper")
public PropertiesFactoryBean mapper() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource("META-INF/spring/application.properties"));
return bean;
}
@Bean
public MyBean myBean() {
return new MyBean();
}
}
MyBean
class where those Properties
are being used, injected using SPeL:public class MyBean {
@Value("#{mapper}")
private Map props;
public Map getProps() {
return props;
}
}
So, in the end you don't use xml (of course), you need to use a PropertiesFactoryBean
to load the .properties file and, using @Value
, Spring will inject the Properties
into a Map. The extra code (compared to, probably, @PropertySource
) is the PropertiesFactoryBean
and you don't need to parse the values in your code manually (compared to your workaround that injects a String[]
).
Hope this helps.
Upvotes: 1
Reputation: 49542
How about defining a bean in your Java config for this?
@Bean
public Map<Integer, String> myProps(Properties properties) {
Map<Integer, String> map = new HashMap<>();
// implement logic to populate map from properties
return map;
}
And in your class:
@Autowirded
Map<Integer, String> map;
Upvotes: 0