2012-07-10 62 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