Reputation: 15975
I have a Map<String, String>
and I would like to tell Spring to use this when creating beans and resolving property placeholders. What is the easiest way to do this? Here is an example:
@Component
public class MyClass {
private String myValue;
@Autowired
public MyClass(@Value("${key.in.map}") String myValue) {
this.myValue = myValue;
}
public String getMyValue() {
return myValue;
}
}
public static void main(String[] args) {
Map<String, String> propertyMap = new HashMap<>();
propertyMap.put("key.in.map", "value.in.map");
ApplicationContext ctx = ...;
// Do something???
ctx.getBean(MyClass.class).getMyValue(); // Should return "value.in.map"
}
Upvotes: 7
Views: 2387
Reputation: 280132
Spring provides a MapPropertySource
which you can register with your ApplicationContext
's Environment
(you'll need a ConfigurableEnvironment
which most ApplicationContext
implementations provide).
These registered PropertySource
values are used by the resolvers (in order) to find a value for your placeholder names.
Here's a complete example:
@Configuration
@ComponentScan
public class Example {
@Bean
public static PropertySourcesPlaceholderConfigurer configurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
// can also add it here
//configurer.setPropertySources(propertySources);
return configurer;
}
public static void main(String[] args) {
Map<String, Object> propertyMap = new HashMap<>();
propertyMap.put("key.in.map", "value.in.map");
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MapPropertySource propertySource = new MapPropertySource("map-source", propertyMap);
ctx.getEnvironment().getPropertySources().addLast(propertySource);
ctx.register(Example.class);
ctx.refresh();
MyClass instance = ctx.getBean(MyClass.class);
System.out.println(instance.getMyValue());
}
}
@Component
class MyClass {
private String myValue;
@Autowired
public MyClass(@Value("${key.in.map}") String myValue) {
this.myValue = myValue;
}
public String getMyValue() {
return myValue;
}
}
Upvotes: 3
Reputation: 3514
I was able to achieve the similar functionality although may not what you're looking.
Here's my code:
application.properties
key.in.map=value.in.map
beans.xml
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.chatar" />
</beans:beans>
Config.java
package com.chatar.batch;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
@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;
}
}
MyClazz.java
package com.chatar.batch;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class MyClazz {
@Value("#{mapper}")
private Map<String, String> props;
public Map<String, String> getProps() {
return props;
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("Value:: " + context.getBean(MyClazz.class).getProps().get("key.in.map")); // Should return
}
}
Output: Value:: value.in.map
Upvotes: -1
Reputation: 15975
Here is the solution I ended up using. I convert the Map to a properties file.
Map<String, String> propertyMap = ...;
Properties properties = new Properties();
properties.putAll(propertyMap);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ConfigurableBeanFactory beanFactory = ctx.getBeanFactory();
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setProperties(properties);
beanFactory.registerSingleton(PropertySourcesPlaceholderConfigurer.class.getSimpleName(),
propertySourcesPlaceholderConfigurer);
Upvotes: 0