Programmatic access to properties created by property-placeholder

后端 未结 9 2387
长情又很酷
长情又很酷 2020-11-29 20:21

I\'m reading properties file using context:property-placeholder. How can I access them programatically (@Value doesn\'t work - I d

相关标签:
9条回答
  • Spring follows Inversion Of Control approach, this means that we can simply inject particular property into POJO. But there are some cases, when you would like to access property given by name directly from your code - some might see it as anti-pattern - this is palpably true, but lets concentrate on how to do it.

    The PropertiesAccessor below provides access to properties loaded by Property Placeholder and encapsulates container specific stuff. It also caches found properties because call on AbstractBeanFactory#resolveEmbeddedValue(String) is not cheap.

    @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; 
        } 
    }
    
    0 讨论(0)
  • 2020-11-29 20:56

    Found answer at below site:

    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>
    
    0 讨论(0)
  • 2020-11-29 20:59

    This works if you need to scan multiple locations for your properties ...

    <bean id="yourProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <array value-type="org.springframework.core.io.Resource">
                <value>classpath:yourProperties.properties</value>
                <value>file:../conf/yourProperties.properties</value>
                <value>file:conf/yourProperties.properties</value>
                <value>file:yourProperties.properties</value>
            </array>
        </property>
        <property name="ignoreResourceNotFound" value="true" />
    </bean>
    <context:property-placeholder properties-ref="yourProperties" ignore-unresolvable="true"/>
    

    And then in your actual classes ...

    @Autowired
    Properties yourProperties;
    

    Tested using Spring 5.1.4

    0 讨论(0)
  • 2020-11-29 21:10

    Let's asume that you the properties file defined in that "parent" framework

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

    You can use the @Value annotation in this way:

    @Value( value = "#{applicationProperties['my.app.property']}" )
    private String myProperty;
    
    0 讨论(0)
  • 2020-11-29 21:12
    <util:properties id="prop" location="location of prop file" />
    

    This return java.util.Properties object

    In JAVA Code

    Properties prop = (Properties) context.getBean("prop");
    

    Now you can access ,

    prop.getProperty("key");
    
    0 讨论(0)
  • 2020-11-29 21:13
    @Value
    

    annotation works on new releases of Spring (tested on v3.2.2) Here is how it is done:

    1. Map your properties file in spring configuration file

      <!--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. Create app-config.properties inside (root) your source folder

      my.property=test
      my.property2=test2
      
    3. Create a controller class

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

    Spring will automatically map the content of my.property to your variable inside the controller

    Mapping to a list

    Property value:

    my.list.property=test,test2,test3
    

    Controller class configuration:

    @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);
        }
    }
    

    Property value:

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

    Controller class:

    @Value("#{PropertySplitter.map('${my.complex.property}')}")
    Map<String, String> myComplexProperty;
    
    0 讨论(0)
提交回复
热议问题