Spring: Environment specific configuration
environment-variables, java, properties, spring
Solution
I use for this purpose a subcass of `PropertyPlaceholderConfigurer`:
public class EnvironmentPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private static final String ENVIRONMENT_NAME = "targetEnvironment";
private String environment;
public EnvironmentPropertyPlaceholderConfigurer() {
super();
String env = resolveSystemProperty(ENVIRONMENT_NAME);
if (StringUtils.isNotEmpty(env)) {
environment = env;
}
}
@Override
protected String resolvePlaceholder(String placeholder, Properties props) {
if (environment != null) {
String value = props.getProperty(String.format("%s.%s", environment, placeholder));
if (value != null) {
return value;
}
}
return super.resolvePlaceholder(placeholder, props);
}
}
and using it in `applicationContext.xml` (or any other spring-configuration file):
<bean id="propertyPlaceholder"class="EnvironmentPropertyPlaceholderConfigurer">
<property name="location" value="classpath:my.properties" />
</bean>
In `my.properties` you can define properties like:
db.driverClassName=org.mariadb.jdbc.Driver
db.url=jdbc:mysql:///MyDB
db.username=user
db.password=secret
prod.db.username=prod-user
prod.db.password=verysecret
test.db.password=notsosecret
Thereby you can prefix properties keys by an environment key (e.g. `prod`).
Using the vm argument `targetEnvironment` you can choose the enviroment you like to use, e.g. `-DtargetEnvironment=prod`.
If no environment-specific-property exists, the default one (without a prefix) is choosen. (You should always define a default one.)
Problem
Using Spring I need some kind of environment (dev|test|prod) specific properties. I have exactly one configuration file (myapp.properties) and for some reasons I cannot have more than one configuration file (even spring can handle more than one). So I need the possibility to add properties with a prefix like ``` dev.db.user=foo prod.db.user=foo ``` and tell the application which prefix (environment) to use with a VM-argument like `-Denv-target` or something like this.