2012-07-10 85 views
30

我正在使用context:property-placeholder讀取屬性文件。我如何訪問它們以編程方式@Value不起作用 - 我不知道在開發時屬性標題)?以編程方式訪問屬性佔位符創建的屬性

的主要問題是,因爲它是設置好的增長「父」框架

PS我不能改變applicationContext.xml文件。這很奇怪,但Environment.getProperty返回null

+0

請訪問http:// stackoverflow.com/questions/5172392/how-to-programmatically-resolve-property-placeholder-in-spring。從春季3開始似乎是可能的。 – Vadzim 2013-03-28 15:40:14

回答

4

Spring遵循Inversion Of Control方法,這意味着我們可以簡單地將特定的屬性注入到POJO中。但是有些情況下,當你想直接從你的代碼中獲得由名字給出的屬性時 - 有些人可能認爲它是反模式 - 這很明顯,但讓我們專注於如何去做。

下面的PropertiesAccessor提供對Property Placeholder加載的屬性的訪問,並封裝容器特定的內容。它也緩存找到的屬性,因爲在AbstractBeanFactory#resolveEmbeddedValue(String)上調用並不便宜。

@Named 
public class PropertiesAccessor { 

    private final AbstractBeanFactory beanFactory; 

    private final Map<String,String> cache = new ConcurrentHashMap<>(); 

    @Inject 
    protected PropertiesAccessor(AbstractBeanFactory beanFactory) { 
     this.beanFactory = beanFactory; 
    } 

    public String getProperty(String key) { 
     if(cache.containsKey(key)){ 
      return cache.get(key); 
     } 

     String foundProp = null; 
     try { 
      foundProp = beanFactory.resolveEmbeddedValue("${" + key.trim() + "}");   
      cache.put(key,foundProp);   
     } catch (IllegalArgumentException ex) { 
      // ok - property was not found 
     } 

     return foundProp; 
    } 
} 
9
@Value 

註釋適用於(在V3.2.2測試)春天的新版本 這裏是它是如何做:

  1. 地圖你的屬性在Spring配置文件文件

    <!--Import Info: 
    xmlns:context="http://www.springframework.org/schema/context" 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd--> 
    
    <context:property-placeholder location="classpath:/app-config.properties" /> 
    
  2. 在你的源文件夾裏面(root)創建app-config.properties

    my.property=test 
    my.property2=test2 
    
  3. 創建一個控制器類

    @Controller 
    public class XRDSBuilder 
    { 
        @Value("${my.property}") 
        private String myProperty; 
    
        public String getMyProperty() { return myProperty; } 
    } 
    

Spring會自動映射我的內容。屬性爲您的變量控制器

Mapping to a list

屬性值內:

my.list.property=test,test2,test3 

Controller類配置:

@Value("#{'${my.list.property}'.split(',')}") 
private List<String> myListProperty; 

Advanced mapping

@Component("PropertySplitter") 
public class PropertySplitter { 

    /** 
    * Example: one.example.property = KEY1:VALUE1,KEY2:VALUE2 
    */ 
    public Map<String, String> map(String property) { 
     return this.map(property, ","); 
    } 

    /** 
    * Example: one.example.property = KEY1:VALUE1.1,VALUE1.2;KEY2:VALUE2.1,VALUE2.2 
    */ 
    public Map<String, List<String>> mapOfList(String property) { 
     Map<String, String> map = this.map(property, ";"); 

     Map<String, List<String>> mapOfList = new HashMap<>(); 
     for (Entry<String, String> entry : map.entrySet()) { 
      mapOfList.put(entry.getKey(), this.list(entry.getValue())); 
     } 

     return mapOfList; 
    } 

    /** 
    * Example: one.example.property = VALUE1,VALUE2,VALUE3,VALUE4 
    */ 
    public List<String> list(String property) { 
     return this.list(property, ","); 
    } 

    /** 
    * Example: one.example.property = VALUE1.1,VALUE1.2;VALUE2.1,VALUE2.2 
    */ 
    public List<List<String>> groupedList(String property) { 
     List<String> unGroupedList = this.list(property, ";"); 

     List<List<String>> groupedList = new ArrayList<>(); 
     for (String group : unGroupedList) { 
      groupedList.add(this.list(group)); 
     } 

     return groupedList; 

    } 

    private List<String> list(String property, String splitter) { 
     return Splitter.on(splitter).omitEmptyStrings().trimResults().splitToList(property); 
    } 

    private Map<String, String> map(String property, String splitter) { 
     return Splitter.on(splitter).omitEmptyStrings().trimResults().withKeyValueSeparator(":").split(property); 
    } 
} 

屬性值:

my.complex.property=test1:value1,test2:value2 

控制器類:

@Value("#{PropertySplitter.map('${my.complex.property}')}") 
Map<String, String> myComplexProperty; 
+1

這並不回答所述的問題。 – Joel 2015-11-12 19:17:33

+0

完美答案:) – Manoj 2016-08-17 10:59:21

+0

是否與curren Mule ESB 3.7.3運行時一起工作?我無法達成解決方案,它給了我一個錯誤,例如'無法將'java.util.ArrayList'類型的屬性值轉換爲屬性'messageProcessors''所需的類型'java.util.List' – Hayra 2016-08-18 11:42:29

2
在以下網站

找到答案:

http://forum.spring.io/forum/spring-projects/container/106180-programmatic-access-to-properties-defined-for-the-propertyplaceholderconfigurer

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer"> 
<property name="properties" ref="props" /> 
</bean> 
<bean id="props" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="location" value="file:C:/CONFIG/settings.properties"/> 
</bean> 
6

我們用下面的方法來訪問屬性我們應用程序

<util:properties id="appProperties" location="classpath:app-config.properties" /> 
<context:property-placeholder properties-ref="appProperties"/> 

然後,您可以使用限定符將屬性自動裝配到bean中。

@Component 
public class PropertyAccessBean { 

    private Properties properties; 

    @Autowired 
    @Qualifier("appProperties") 
    public void setProperties(Properties properties) { 
     this.properties = properties; 
    } 

    public void doSomething() { 
     String property = properties.getProperty("code.version"); 
    } 

} 

如果你有更復雜的屬性,你仍然可以使用ignore-resource-not-found和ignore-unresolvable。我們使用這種方法來外化我們的一些應用程序設置。

<util:properties id="appProperties" ignore-resource-not-found="true" 
    location="classpath:build.properties,classpath:application.properties, 
          file:/data/override.properties"/> 
<context:property-placeholder ignore-unresolvable="true" properties-ref="appProperties"/> 
-1

讓我們asume你在 「父」 框架中定義的屬性文件

<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="location" value="classpath:main.properties" /> 
</bean> 

可以使用@Value註釋中這樣說:

@Value(value = "#{applicationProperties['my.app.property']}") 
private String myProperty; 
+0

它在春季4面對錯誤: 索引進式「org.springframework.beans.factory.config.PropertyPlaceholderConfigurer」不支持 – 2017-09-14 05:46:24

+0

像@SeanPatrickFloyd評論說:「_similar問題再次出現再次,建議的解決方案通常是子類PropertyPlaceHolderConfigurer,並使該屬性可用於上下文手動。或使用** PropertiesFactoryBean ** _。「我希望這可以幫助你:[閱讀價值從屬性文件在運行時](https://stackoverflow.com/questions/5665296/reading-valued-from-properties-file-at-runtime/5673678# 5673678) – 2017-10-23 13:59:02