2015-06-07 22 views
6

我有一個Map<String, String>,我想告訴Spring在創建bean和解析屬性佔位符時使用它。什麼是最簡單的方法來做到這一點?這裏是一個例子:如何告訴Spring使用Java映射解析屬性佔位符?

@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" 
} 
+0

是否可以將Map鍵注入到次級的spring bean屬性中。首先你要做'新的HashMap <>();'。 Spring上下文將無法識別這個bean。你必須通過類似'ctx.getBean(java.util.HashMap.class)'的方式從Spring Context獲得這個bean。然後[這裏](http://stackoverflow.com/questions/27285202/inject-map-of-beans-using-spring-from-properties-file)是用戶能夠使用'

+0

@ Amit.rk3感謝輸入Amrit。我不確定你完全瞭解這個設置。我對'ctx.getBean(HashMap.class)'不感興趣。我有一個String到String的映射,我想告訴Spring使用這個映射來解析屬性佔位符。 – Max

+0

好的。在你的問題中你提到了java map。這讓我感到困惑:)。無論如何,只需從屬性列表映射字符串,就可以將條目保存在.properties文件中並加載它。對此有很多答案。 –

回答

3

Spring提供了一個MapPropertySource您可以與您的註冊ApplicationContextEnvironment(你需要一個ConfigurableEnvironment其中大部分ApplicationContext實現提供)。

這些已註冊的PropertySource值由解析器(按順序)用於查找佔位符名稱的值。

這裏有一個完整的例子:

@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; 
    } 
} 
+0

感謝您的回答。行爲與直接使用屬性文件有什麼不同?例如,如果您嘗試執行@Value(「my.int.key」)int myValue',會發生什麼情況? – Max

+0

@Max當你註冊一個屬性文件時,Spring在後臺註冊一個'PropertiesPropertySource'。這些按照某種順序註冊。 'PropertySourcesPlaceholderConfigurer'迭代源代碼,試圖找到一個給定的屬性,例如。 'my.int.key'。如果有,它會使用它。如果沒有,它會繼續前進,直到沒有剩餘的來源。此時它會拋出異常。 –

+0

但屬性文件是字符串 - >字符串的映射,因爲文件中沒有可用的類型信息。 MapPropertySource的類型是string - > object的映射。 「int」的例子是問我是否需要照顧轉換'int'類型? – Max

-1

我能夠實現類似的功能,雖然可能不是你在找什麼。

這裏是我的代碼:

application.properties

key.in.map=value.in.map 

的beans.xml

http://www.springframework.org/schema/批次http://www.springframework.org/schema/batch/spring-batch-2.1.xsd http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/contexthttp://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 
    } 
} 

輸出:值:: value.in.map

+0

感謝您的詳細解答。這不正是我所期待的,但它給了我一些好主意。 – Max

0

這裏是我結束了使用該解決方案。我將地圖轉換爲屬性文件。

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

這樣做! :)。 –

相關問題