I have a requirement to have all our properties files be stored in a directory. The location of this directory should be stored in a system environment variable. In my appli
In Spring.Net we have got the IVariableSource interface and PropertyPlaceholderConfigurer which are able to retrieve values from environment variables. Maybe there is something similar in the Spring Framework for Java?
Edit: I think I found the corresponding java bean which is named PropertyPlaceholderConfigurer as well in the java docs.
We later upgraded to Spring 3.0.X and we were able to take advantage of the spring expression language. Our approach simplified from three beans to the following snippet:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:defaults.properties</value>
<value>file:/a/defined/location/project.properties</value>
<value>file:${AN_ENV_CONFIGURED_DIR}/project.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
<property name="searchSystemEnvironment" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
This allowed us to have either a development (the first defaults) statically well known location, or a deployed location configured via env variables. The configurer processes these in order (i.e. the deployed takes precedence over the defaults).
I ended up going with a non programmatic approach. I used a MethodInvoker to retrieve the environment value. I was able to then pass that into the FileSystemResource.
<bean id="configPath" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" >
<property name="targetClass" value="java.lang.String" />
<property name="staticMethod" value="java.lang.System.getenv" />
<property name="arguments">
<list>
<value>NAME_OF_VARIABLE</value>
</list>
</property>
</bean>
while I note that the question required 2.5.x, it's worth pointing out that Spring 3's EL support (available since Nov 2009) would've made short work of this sort of thing
@Value("#{ systemProperties['user.home'] }")
private String userHome ;
or
<property name = "userHome" value ="#{ systemProperties['user.home'] }"/>
Example:
Start you app with -DDA_HOME=c:\temp
c:\temp must contain directory called "config"
In c:\temp\config you have file app.properties (for example)
Extend the Spring loader:
public class Loader extends org.springframework.beans.factory.config.PropertyPlaceholderConfigurer{
private String appHome;
public void setAppHome(String appHome) {
this.appHome = appHome;
}
@Override
public void setLocation(Resource location) {
if(appHome==null){
throw new RuntimeException("You must specify VM property DA_HOME, this directory must contain " +
"another directory, called config, inside the config directory app.properties " +
"file must be found with the configuration properties");
}
String configurationDirectory = appHome + System.getProperty("file.separator") + "config";
String fileName = location.getFilename();
Resource file = new FileSystemResource( configurationDirectory + System.getProperty("file.separator")+ fileName);
super.setLocation(file);
}
}
Specify the new loader and its configuration base:
<bean id="placeholderConfig" class="your.Loader">
<property name="appHome" value="#{systemProperties['DA_HOME']}"/>
<property name="location" value="app.properties" />
</bean>
You could always extend the FileSystemResource (i.e. PropertiesFileResource) that would initialize itself by taking prepending the property file location system property to the file path.