How can I tell Spring to use a Java map to resolve a property placeholder?

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" } 
+6
source share
3 answers

Spring provides a MapPropertySource that you can register with the ApplicationContext Environment (you'll need a ConfigurableEnvironment , which provides most implementations of ApplicationContext ).

These registered PropertySource values ​​are used by resolvers (in order) to find the value for your placeholder names.

Here is 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; } } 
+3
source

Here is the solution I used. I convert a 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); 
0
source

I was able to achieve similar functionality, although perhaps not what you are looking for.

Here is 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

-1
source

Source: https://habr.com/ru/post/988651/


All Articles