用Spring以编程方式访问属性文件?

我们使用下面的代码从属性文件中注入属性。

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations" value="classpath:/my.properties"/> </bean> <bean id="blah" class="abc"> <property name="path" value="${the.path}"/> </bean> 

有没有一种方法,我们可以通过编程访问属性? 我试图做一些代码,而不dependency injection。 所以我想只是有这样的代码:

 PropertyPlaceholderConfigurer props = new PropertyPlaceholderConfigurer(); props.load("classpath:/my.properties"); props.get("path"); 

怎么样PropertiesLoaderUtils ?

 Resource resource = new ClassPathResource("/my.properties"); Properties props = PropertiesLoaderUtils.loadProperties(resource); 

CREDIT : 在没有重新读取属性文件的情况下编程访问Spring中的属性

我发现了一个很好的实现,以编程方式访问属性在spring没有重新加载相同的属性,spring已经加载。 [另外,不需要在源代码中对属性文件位置进行硬编码]

随着这些变化,代码看起来更清洁和可维护。

概念很简单。 只要扩展Spring的默认属性占位符(PropertyPlaceholderConfigurer)并捕获它在本地variables中加载的属性即可

 public class SpringPropertiesUtil extends PropertyPlaceholderConfigurer { private static Map<String, String> propertiesMap; // Default as in PropertyPlaceholderConfigurer private int springSystemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK; @Override public void setSystemPropertiesMode(int systemPropertiesMode) { super.setSystemPropertiesMode(systemPropertiesMode); springSystemPropertiesMode = systemPropertiesMode; } @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { super.processProperties(beanFactory, props); propertiesMap = new HashMap<String, String>(); for (Object key : props.keySet()) { String keyStr = key.toString(); String valueStr = resolvePlaceholder(keyStr, props, springSystemPropertiesMode); propertiesMap.put(keyStr, valueStr); } } public static String getProperty(String name) { return propertiesMap.get(name).toString(); } } 

用法示例

 SpringPropertiesUtil.getProperty("myProperty") 

弹簧configuration更改

 <bean id="placeholderConfigMM" class="SpringPropertiesUtil"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> <property name="locations"> <list> <value>classpath:myproperties.properties</value> </list> </property> </bean> 

希望这有助于解决您的问题

我已经完成了这个工作。

 Properties props = PropertiesLoaderUtils.loadAllProperties("my.properties"); PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer(); props2.setProperties(props); 

这应该工作。

如果您只想从代码访问占位符值,则存在@Value注释:

 @Value("${settings.some.property}") String someValue; 

要访问占位符从SPEL使用此语法:

 #('${settings.some.property}') 

要将configuration公开到closuresSPEL的视图,可以使用这个技巧:

 package com.my.app; import java.util.Collection; import java.util.Map; import java.util.Set; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.stereotype.Component; @Component public class PropertyPlaceholderExposer implements Map<String, String>, BeanFactoryAware { ConfigurableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = (ConfigurableBeanFactory) beanFactory; } protected String resolveProperty(String name) { String rv = beanFactory.resolveEmbeddedValue("${" + name + "}"); return rv; } @Override public String get(Object key) { return resolveProperty(key.toString()); } @Override public boolean containsKey(Object key) { try { resolveProperty(key.toString()); return true; } catch(Exception e) { return false; } } @Override public boolean isEmpty() { return false; } @Override public Set<String> keySet() { throw new UnsupportedOperationException(); } @Override public Set<java.util.Map.Entry<String, String>> entrySet() { throw new UnsupportedOperationException(); } @Override public Collection<String> values() { throw new UnsupportedOperationException(); } @Override public int size() { throw new UnsupportedOperationException(); } @Override public boolean containsValue(Object value) { throw new UnsupportedOperationException(); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public String put(String key, String value) { throw new UnsupportedOperationException(); } @Override public String remove(Object key) { throw new UnsupportedOperationException(); } @Override public void putAll(Map<? extends String, ? extends String> t) { throw new UnsupportedOperationException(); } } 

然后使用该公开者将属性公开给视图:

 <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/> <property name="attributesMap"> <map> <entry key="config"> <bean class="com.my.app.PropertyPlaceholderExposer" /> </entry> </map> </property> </bean> 

然后在视图中,使用像这样的公开的属性:

 ${config['settings.some.property']} 

这个解决scheme的优点是,您可以依赖上下文注入的标准占位符实现:property-placeholder标记。

现在最后要说明的是,如果您确实需要捕获所有占位符属性及其值,则必须通过StringValueResolverpipe道来确保占位符在预期的属性值内工作。 下面的代码将做到这一点。

 package com.my.app; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.util.StringValueResolver; public class AppConfig extends PropertyPlaceholderConfigurer implements Map<String, String> { Map<String, String> props = new HashMap<String, String>(); @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { this.props.clear(); for (Entry<Object, Object> e: props.entrySet()) this.props.put(e.getKey().toString(), e.getValue().toString()); super.processProperties(beanFactory, props); } @Override protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, StringValueResolver valueResolver) { super.doProcessProperties(beanFactoryToProcess, valueResolver); for(Entry<String, String> e: props.entrySet()) e.setValue(valueResolver.resolveStringValue(e.getValue())); } // Implement map interface to access stored properties @Override public Set<String> keySet() { return props.keySet(); } @Override public Set<java.util.Map.Entry<String, String>> entrySet() { return props.entrySet(); } @Override public Collection<String> values() { return props.values(); } @Override public int size() { return props.size(); } @Override public boolean isEmpty() { return props.isEmpty(); } @Override public boolean containsValue(Object value) { return props.containsValue(value); } @Override public boolean containsKey(Object key) { return props.containsKey(key); } @Override public String get(Object key) { return props.get(key); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public String put(String key, String value) { throw new UnsupportedOperationException(); } @Override public String remove(Object key) { throw new UnsupportedOperationException(); } @Override public void putAll(Map<? extends String, ? extends String> t) { throw new UnsupportedOperationException(); } } 

你也可以使用spring utils,或者通过PropertiesFactoryBean加载属性。

 <util:properties id="myProps" location="classpath:com/foo/myprops.properties"/> 

要么:

 <bean id="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="location" value="classpath:com/foo/myprops.properties"/> </bean> 

然后你可以在你的应用程序中select:

 @Resource(name = "myProps") private Properties myProps; 

另外在你的configuration中使用这些属性:

 <context:property-placeholder properties-ref="myProps"/> 

这也在文档中: http : //docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#xsd-config-body-schemas-util-properties

创build一个类如下

  package com.tmghealth.common.util; import java.util.Properties; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @Configuration @PropertySource(value = { "classpath:/spring/server-urls.properties" }) public class PropertiesReader extends PropertyPlaceholderConfigurer { @Override protected void processProperties( ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { super.processProperties(beanFactory, props); } } 

然后,无论你想访问一个属性使用

  @Autowired private Environment environment; and getters and setters then access using environment.getProperty(envName + ".letter.fdi.letterdetails.restServiceUrl"); 

– 在访问器类中写入getter和setter

  public Environment getEnvironment() { return environment; }`enter code here` public void setEnvironment(Environment environment) { this.environment = environment; } 

这是另一个样本。

 XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml")); PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer(); cfg.setLocation(new FileSystemResource("jdbc.properties")); cfg.postProcessBeanFactory(factory); 

这将解决任何嵌套的属性。

 public class Environment extends PropertyPlaceholderConfigurer { /** * Map that hold all the properties. */ private Map<String, String> propertiesMap; /** * Iterate through all the Propery keys and build a Map, resolve all the nested values before beuilding the map. */ @Override protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { super.processProperties(beanFactory, props); propertiesMap = new HashMap<String, String>(); for (Object key : props.keySet()) { String keyStr = key.toString(); String valueStr = beanFactory.resolveEmbeddedValue(placeholderPrefix + keyStr.trim() + DEFAULT_PLACEHOLDER_SUFFIX); propertiesMap.put(keyStr, valueStr); } } /** * This method gets the String value for a given String key for the property files. * * @param name - Key for which the value needs to be reterieved. * @return Value */ public String getProperty(String name) { return propertiesMap.get(name).toString(); } 

这篇文章还解释了如何访问属性: http ://maciej-miklas.blogspot.de/2013/07/spring-31-programmatic-access-to.html

你可以通过这个spring bean访问spring属性占位符加载的属性:

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

这帮助我:

 ApplicationContextUtils.getApplicationContext().getEnvironment()