Spring 3.1 M1: Unified Property Management |
|

In the first two posts of this series, I described the bean definition profiles feature, and how it relates to the Environment abstraction new in Spring 3.1 M1. Today we'll take a look at a second aspect of the Environment — how it helps simplify the concern of configuration property management.
Understanding property sources
Spring's Environment abstraction provides search operations over a configurable hierarchy of property sources. To explain fully, consider the following:
ApplicationContext ctx = new GenericApplicationContext();
Environment env = ctx.getEnvironment();
boolean containsFoo = env.containsProperty("foo");
System.out.println("Does my environment contain the 'foo' property? " + containsFoo);
In the snippet above, we see a high-level way of asking Spring whether the 'foo' property is defined for the current environment. To answer this question, the Environment object performs a search over a set of PropertySource objects. A PropertySource is a simple abstraction over any source of key-value pairs, and Spring's DefaultEnvironment is configured with two PropertySource objects — one representing the set of JVM system properties (a la System.getProperties()) and one representing the set of system environment variables (a la System.getenv())[1]. This means that if a 'foo' system property or 'foo' environment variable is present at runtime, the call to env.containsProperty("foo") will return true.
The search performed is hierarchical. By default, system properties have precedence over environment variables, so if the 'foo' property happens to be set in both places during a call to env.getProperty("foo"), the system property value will 'win' and be returned preferentially over the environment variable.
Most importantly, the entire mechanism is configurable. Perhaps you have a custom source of properties that you'd like to integrate into this search. No problem — simply implement and instantiate your own PropertySource and add it to the set of PropertySources for the current Environment:
ConfigurableApplicationContext ctx = new GenericApplicationContext(); MutablePropertySources sources = ctx.getEnvironment().getPropertySources(); sources.addFirst(new MyPropertySource());
In the code above, MyPropertySource has been added with highest precedence in the search. If it contains a 'foo' property, it will be detected and returned ahead of any 'foo' property in any other PropertySource. The MutablePropertySources API exposes a number of methods that allow for precise manipulation of the set of property sources. Explore the Javadoc for full details.
Putting property sources to use
Now that you understand the basics of property sources and their relationship to the Environment, you might be wondering how all of this is relevant to you as a developer of Spring applications. Let's consider a couple of scenarios and see how it all comes together.
Scenario 1: ${placeholder} resolution in <import/> statements
You have a set of Spring configuration files that configure beans specific to certain customers of your application, and you conditionally load those files using <import/> statements containing a placeholder resolving to the value of a 'customer' property:
<beans>
<import resource="com/bank/service/${customer}-config.xml"/>
</beans>
Prior to Spring 3.1, the value of placeholders in <import/> elements could be resolved only against JVM system properties or environment variables[2]. No longer is this the case. Because the Environment abstraction is integrated throughout the container, it's easy to route resolution of placeholders through it. This means that you may configure the resolution process in any way you like: change the precedence of searching through system properties and environment variables, or remove them entirely; add your own property sources to the mix as appropriate.
Scenario 2: ${placeholder} resolution in bean definitions
Most Spring users will be familiar with the use of PropertyPlaceholderConfigurer or <context:property-placeholder/> to replace ${...} placeholders in Spring bean definitions. Here is a typical configuration:
<context:property-placeholder location="com/bank/config/datasource.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClass" value="${database.driver}"/>
<property name="jdbcUrl" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
As of Spring 3.1, the <context:property-placeholder/> no longer registers a PropertyPlaceholderConfigurer, but rather a PropertySourcesPlaceholderConfigurer[3]. This component still looks to the datasource.properties file to reslove the ${database.*} placeholders above, but will fall back to the set of PropertySources for the current Environment if the properties are not found in the file. Again this gives you more control; prior to this change, the only fallback options were system properties and environment variables.
Manipulating property sources in a web application
So far we've seen how to access and manipulate property sources in a standalone application where we have programmatic access to an ApplicationContext. In reality, however, many Spring applications are webapps in which the ApplicationContext is managed for you by Spring's ContextLoaderListener. For this reason we've introduced the ApplicationContextInitializer interface and its companion, the contextInitializerClasses servlet context param. Take a look:
web.xml
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.bank.MyInitializer</param-value>
</context-param>
public class MyInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {
public void initialize(ConfigurableWebApplicationContext ctx) {
PropertySource ps = new MyPropertySource();
ctx.getEnvironment().getPropertySources().addFirst(ps);
// perform any other initialization of the context ...
}
}
Implementing and registering an ApplicationContextInitializer provides a simple way to interact with your application context before it is refreshed. This is a perfect place to manipulate property sources, but you could also call setConfigLocations(...) or any other method designed to be called prior to refresh().
Summary
Spring's Environment abstraction provides a single location to configure both profiles and properties. Profiles, as described in earlier posts, determine which bean definitions should be registered for a given deployment context; the property support described in this post provides a consistent abstraction over any source of properties, resulting in more flexible property access and placeholder resolution throughout your application configuration.
In the next post in this series we'll take a look at how Spring 3.1 makes 100% Java-based (read: XML-free) application configuration a reality with FeatureSpecification support — an natural evolution out of the @Configuration class support introduced in Spring 3.0.
Footnotes
[1]: These default property sources are present for DefaultEnvironment, for use in standalone applications. DefaultWebEnvironment is populated with additional default property sources including servlet config and servlet context parameters. DefaultPortletEnvironment similarly has access to portlet config and portlet context parameters as property sources. Both can optionally enable a JndiPropertySource. See Javadoc for details.
[2]: Because processing of <import/> elements necessarily occurs before BeanFactoryPostProcessors are invoked, meaning that even PropertyPlaceholderConfigurer could not help here. Because the Environment and its set of PropertySources are configured before container refresh, placeholders in <import/> elements can be resolved against the Environment without any lifecycle issues.
[3]: In certain cases, <context:property-placeholder/> will still register a PropertyPlaceholderConfigurer. In the 3.1 version of the spring-context schema, the system-properties-mode attribute has been removed from the property-placeholder element. This is because this attribute no longer makes sense in a PropertySources-/Environment-aware world. However, if you build against Spring 3.1 but still use the spring-context-3.0.xsd schema and set the system-properties-mode attribute, <context:property-placeholder> will revert to registering a PropertyPlaceholderConfigurer in order to honor the exact semantics of this setting. This approach preserves backward compatibility in any case.
Similar Posts
- Spring 3.1 M2: Configuration Enhancements
- Bundlor Version Expansion and Property Substitution
- Spring Framework 3.1 goes GA
- Spring Framework 3.1 M1 released
- Using Cloud Foundry Services with Spring: Part 4 – Spring Profiles





Chetan says:
Added on February 17th, 2011 at 12:58 amThis is quite a useful feature and was something I was looking for.
One place where I would like Spring to provide more configuration support is in filtering in resource scanning. For e.g. we use a pattern like classpath:META-INF/spring/module-context.xml for contextConfigLocation to load the Spring config which is packaged in various jar files.
However at times it is required to filter out some config files … sort of deselecting a jar config from being part of Spring context. Currently this logic is baked in ResourceResolver used by Spring ApplicationContext. if we can have a support very similar to one you provide for properties then it would allow complete control in what gets loaded.
Matthew Adams says:
Added on February 21st, 2011 at 10:51 amLoving the whole Profile/Environment/PropertySource karmic enchilada. Nice. I've felt firsthand the pain of not being able to use property placeholders in elements! Profiles will enable folks to switch between dev/test/prod environments much more easily. Further, I can see Environment plus PropertySource features making multitenancy quite a bit easier to configure as well!
Max Alexejev says:
Added on February 28th, 2011 at 6:08 amThank you for the informative post, Chris.
I switched to 3.1.0.M1 in one of my personal projects and met a little (I suspect) problem with behavior. I described the problem in this forum thread
http://forum.springsource.org/showthread.php?p=348248
Any comments are highly appreciated.
Istvan Soos says:
Added on March 2nd, 2011 at 6:14 pmGosh, I missed this feature in the last few years very much. I have just published a blog entry how to make the import statements work with the bean definitions, using the refreshable application context. Anyway, I hope it helps for the folks still on 3.0 or even 2.5:
http://www.drillio.com/en/software-development/spring/context-bootstrapping-with-different-environment-configurations/
wims.tijd says:
Added on March 7th, 2011 at 12:20 pmexcellent separation of environments !
with :
org.mortbay.jetty
maven-jetty-plugin
spring.profiles.active
standalone
Chris Beams (blog author) says:
Added on March 11th, 2011 at 12:21 am@Max – I've replied to the forum post; check it out.
@Chetan – you may be able to accomplish what you need with a combination of using the new <beans profile="…"/> attribute and <import/> elements nested within those profile-specific elements. See my earlier post explaining profile support if you haven't already. Can this meet your needs?
Paul Wilson says:
Added on December 14th, 2011 at 12:24 pmGreat work, I've been looking forward to this feature for a while. Since our property configuration may change over time, it would be nice to be able to periodically refresh a property source, is there support for this?
Paul Wilson says:
Added on December 14th, 2011 at 12:27 pmActually, I can see that this wouldn't be supportable since they may be fundamental to the application configuration – perhaps the dynamic scripting language support would be the place to look.
Joshua says:
Added on May 29th, 2012 at 10:00 amI saw that there is support for specifying active profiles in unit tests. Is there also support for initializing the context with an additional propertysource in unit tests as well?
If so, how would that be done?
Thanks,
Joshua
Sam Brannen (blog author) says:
Added on June 4th, 2012 at 5:25 pmHi Joshua,
In Spring 3.2 we plan to add support for declaratively specifying ApplicationContextInitializers in the Spring TestContext Framework. You could then configure PropertySources in your own custom initializer.
Feel free to watch SPR-9011 to stay up to date on the progress.
Regards,
Sam
Kimberly Smith says:
Added on November 28th, 2012 at 9:24 amTo learn more about property management trends and furnished rentals get the free Annual CHBO Report just by completing the Annual Survey – To complete the survey, visit
https://www.surveymonkey.com/s/2012CHBOSurvey. The first 50 people to
complete the survey will receive a $5 Amazon.com gift card and all
entrants will be entered to receive a free Kindle Fire courtesy of
CHBO. Winner will be chosen at random from those that complete the
survey. All emails collected will be kept confidential.
levk says:
Added on December 12th, 2012 at 2:45 pmIs it possible to do recursive expansion on a variable value, so I could define variables in terms of other variables? I couldn't find anything on this, just tried making a properties file with "my.test=${TEST}" and defined an environment variable TEST, but my.test value is literally ${TEST}, it would be really nice if this was possible.
Jared says:
Added on January 16th, 2013 at 2:28 pmThere are many different types of property management software's available. Looks easy enough to use and customize! Thanks for sharing.
Jared@ Chicago Property Management Company
Stephen says:
Added on February 17th, 2013 at 9:58 pmThese are the most useful information regarding property Sources use. Thanks for sharing these information.
James Bloom says:
Added on April 2nd, 2013 at 11:31 amIt would be great to see a similar article covering this topic in relation to the new mocking features for Environment and PropertySource added to Spring 3.2.
Apart Hotel Madrid says:
Added on April 17th, 2013 at 3:44 amI like the way you have posted your information with us.. Thanks!!!
Accommodation Madrid Apartments