Access properties file programmatically with Spring?
How about PropertiesLoaderUtils?
Resource resource = new ClassPathResource("/my.properties");
Properties props = PropertiesLoaderUtils.loadProperties(resource);
I have done this and it has worked.
Properties props = PropertiesLoaderUtils.loadAllProperties("my.properties");
PropertyPlaceholderConfigurer props2 = new PropertyPlaceholderConfigurer();
props2.setProperties(props);
That should work.
If all you want to do is access placeholder value from code, there is the @Value
annotation:
@Value("${settings.some.property}")
String someValue;
To access placeholders From SPEL use this syntax:
#('${settings.some.property}')
To expose configuration to views that have SPEL turned off, one can use this trick:
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(); }
}
And then use the exposer to expose properties to a view:
<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>
Then in view, use the exposed properties like this:
${config['settings.some.property']}
This solution has the advantage that you can rely on standard placeholder implementation injected by the context:property-placeholder tag.
Now as a final note, if you really need a to capture all placeholder properties and their values, you have to pipe them through StringValueResolver to make sure that placeholders work inside the property values as expected. The following code will do that.
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(); }
}