Reputation: 22456
I'm trying to figure out how to get the values of a properties file into my Spring Environment properties.
The pre Spring 3.1 way of doing this would be something like:
<context:property-placeholder location="classpath:my.properties" />
<bean id="myBean" class="com.whatever.MyBean">
<property name="someValue" value="${myProps.value}" />
<!-- etc -->
</bean>
I could have also done this:
public class MyBean {
@Value(value = "#{myProps.value}")
private String someValue;
}
Now that I can ostensibly pull properties from the Environment class, this seems like a much cleaner way of getting properties than using the clunky #{myProps.value} syntax in either my xml or my bean itself.
I tried this in my XML:
<bean
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="location">
<value>classpath:my.properties</value>
</property>
</bean>
But the properties are not added to Environment.
I understand that I can use the PropertySource attribute, but I'm not doing my configuration with annotations.
So how can I set up my bean / xml so that variables setup in my props are available in Environment? Moreover, how can I inject those values into my bean without having to explicitly say "environmentInstance.getProperty("myProps.value")?
Upvotes: 4
Views: 3671
Reputation: 17774
For the web applications
If you want to have Environment populated before the XML bean definitions are processed, you should implement a ApplicationContextInitializer(), as described in the Spring Source blog
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.bank.MyInitializer</param-value>
</context-param>
Here is a slightly modified version of the example from the blog
public class MyInitializer implements
ApplicationContextInitializer<ConfigurableWebApplicationContext> {
public void initialize(ConfigurableWebApplicationContext ctx) {
ResourcePropertySource ps;
try {
ps = new ResourcePropertySource(new ClassPathResource(
"my.properties"));
} catch (IOException e) {
throw new AssertionError("Resources for my.properties not found.");
}
ctx.getEnvironment().getPropertySources().addFirst(ps);
}
}
For the standalone applications
Basically the same thing, you can modify the environment of the AbstractApplicationContext
directly
ResourcePropertySource ps;
try {
ps = new ResourcePropertySource(new ClassPathResource(
"my.properties"));
}catch (IOException e) {
throw new AssertionError("Resources for my.properties not found.");
}
//assuming that ctx is an AbstractApplicationContext
ctx.getEnvironment().getPropertySources().addFirst(ps);
P.S. the earlier version of this answer showed an attempt to modify the Environment from the bean but it seems to be an antipattern spreading on SO, because for sure you would like to have Environment property sources list populated even before the XmlBeanDefinitionReader
starts to process XML to make placeholders work inside the <import/>
statement.
Upvotes: 1
Reputation: 49915
My understanding is also a little addled but this is what I could make out:
<context:property-placeholder
the placeholder will resolve properties against the locally declared properties and can fallback on the property sources declared in the environment, environment itself does not get modified with the new properties. Again,the only way to add properties to the environment itself seems to be through the @PropertySource annotationUpvotes: 0