Environment-specific configuration for a Spring-based web application? Environment-specific configuration for a Spring-based web application? spring spring

Environment-specific configuration for a Spring-based web application?


Don't add logic to your code to test which environment you're running in - that is a recipe for disaster (or at least burning a lot of midnight oil down the road).

You use Spring, so take advantage of it. Use dependency injection to provide environment-specific parameters to your code. E.g. if you need to call a web service with different endpoints in test and production, do something like this:

public class ServiceFacade {    private String endpoint;    public void setEndpoint(String endpoint) {        this.endpoint = endpoint;    }    public void doStuffWithWebService() {        // use the value of endpoint to construct client    }}

Next, use Spring's PropertyPlaceholderConfigurer (or alternatively PropertyOverrideConfigurer) to populate this property from either a .properties file, or from a JVM system property like so:

<bean id="serviceFacade" class="ServiceFacade">    <property name="endpoint" value="${env.endpoint}"/></bean><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    <property name="locations">        <value>classpath:environment.properties</value>    </property></bean>

Now create two (or three, or four) files like so - one for each of the different environments.

In environment-dev.properties:

env.endpoint=http://dev-server:8080/

In environment-test.properties:

env.endpoint=http://test-server:8080/

Now take the appropriate properties file for each environment, rename it to just environment.properties, and copy it to your app server's lib directory or somewhere else where it will appear on your app's classpath. E.g. for Tomcat:

cp environment-dev.properties $CATALINA_HOME/lib/environment.properties

Now deploy your app - Spring will substitute the value "http://dev-server:8080/" when it sets up your endpoint property at runtime.

See the Spring docs for more details on how to load the property values.


It's worth noting that Spring 3.1 M1 introduced profiles support. Which will probably be the ultimate answer to this need. So keep an eye for it.

Meanwhile, I personally do exactly what Pavel described.


We do this in our application but not within the spring config.

During app startup (in a context listener) we read the machine's hostname and store the matching prod,dev,qa info in a static variable.

We don't access the variable directly (though one could) but we have a spring service that interfaces with that variable to give us access to our server environment information.