Stage aware spring contexts part II
As we have seen in the previous post with the @Environment annotation or the EnvironmentAwareSingletonFactoryBean, you can by using them choose between different implementation of Spring beans at runtime. But sometimes it is not the implementation you would like to switch between but the internal configuration of a particular class.
To support this, we have the EnvironmentAwareProperties class. It is a class in where you can register multiple property files used for looking up environment spesific values for a given property key using the environment as a prefix to separate values.
Property file layout
Each property file may have several entries for one key each prefixed by the environment it should apply. If no value found for the environment we are running in, it falls back on the key with no prefix. As shown in the following example
#
# myApp properties
#
myKey=default value
development.myKey=development value
test.myKey=test value
production.myKey=production value
custom.myKey=custom value
You are also allowed to use other property keys in the values, and it will be resolved and replaced with the value of the corresponding key as shown here :
#
# myApp properties
#
baseUrl=http://localhost
development.baseUrl=http://dev.arktekk.no
test.baseUrl=http://test.arktekk.no
production.baseUrl=http://arktekk.no
customerServiceEndpoint=${baseUrl}/services/customerService
orderServiceEndpoint=${baseUrl}/services/mockCustomerService
Configuring and using environment aware properties in Java
EnvironmentAwareProperties properties
= new EnvironmentAwareProperties("myProperties.properties");
String myValue = properties.getProperty("myKey");
There are also constructors taking a list of property files, or you may use the registerPropertiesmethod to register more files. The EnvironmentAwareProperties class uses Spring resource loader to load the property files so you can use all the Spring supported urls, as e.g. classpath:myProperties.properties.
Use in Spring beans
In my opinion I do like spring beans that tries to configure them selves as much as possible. I think there are way to much use of Spring configuration files to configure ordinary properties like database url’s, service end points and so on. So what I would prefer is that we configure a EnvironmentAwareProperties bean in Spring, and then use the Spring autowiring support to get it injected unto other spring beans, and then use the InitializingBean inteface or the new support for the @PostConstruct annotation In this way we only need to configure our spring beans, in the case that the default values does not work in our application. This is best explained in the 2 part example below.
Configuring the EnvironmentAwareProperties bean
First we need to configure our properties in Spring by adding this xml snippet
<bean id="properties"
class="no.arktekk.stagedspring.properties.EnvironmentAwareProperties">
<property name="propertyFiles">
<list>
<value>no/arktekk/stagedspring/properties/test1.properties</value>
</list>
</property>
</bean>
Using in beans
Then it is time to get it injected, and utilized in a spring bean
public class SpringBean {
@Autowired private EnvironmentAwareProperties properties;
@PostConstruct
public void initProperties() throws Exception {
band = properties.getProperty("aCoolBand", "Mothers of invention");
}
Note by using afterPropertiesSet or @PostConstruct this will override any configuration done in Spring configuration files, and the only way to change the values is by using the property files
Overriding properties
EnvironmentAwareProperties uses an ArrayList internally and, in the case of multiple files are registered, you are allowed to use a key in several files. When the EnvironmentAwareProperties class encounters several keys that match, it will always use the key registered last in the class. You may also register a file that does not yet exists, and it will be picked up if it is there at startup
Configuring Spring beans with placeholders
In addition, those of you familiar with Spring probably know the PropertyPlaceHolderConfigurer that Spring ships with. To be able to use this kind of configuration and use stages this project provide a EnvironmentAwarePropertyPlaceHolderConfigurer class that are able to use the EnvironmentAwareProperties class to resolve the values. This functionality is best shown with an example
<bean id="properties"
class="no.arktekk.stagedspring.properties.EnvironmentAwareProperties">
<property name="propertyFiles">
<list>
<value>myProperties.properties</value>
</list>
</property>
</bean>
<bean id="placeHolderConfigurer"
class="no.arktekk.stagedspring.properties.EnvironmentAwarePropertyPlaceholderConfigurer">
<property name="stagedProperties" ref="properties" />
</bean>
<bean id="testBean" class="..TestBean">
<property name="url" value="${aCoolUrl}" />
</bean>
of course the EnvironmentAwareProperties property is marked with the @Autowired annotation so the ref shown above is optional
For more information
Reference documentation and sourcecode is availale at the at project website
About this entry
You’re currently reading “Stage aware spring contexts part II,” an entry on Different aspects of life
- Published:
- Sunday, April 6th, 2008 at 11:37 pm
- Author:
- Kaare Nilsen
- Category:
- Java, Open Source
- Tags:
- Java, Open Source, Spring
No comments
Jump to comment form | comments rss | trackback uri