How can I know the deployment environment of a web application, e.g. whether it is local, dev, qa or prod, etc. Is there any way I can determine this in spring application context file at runtime?
4 Answers
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.

- 3,481
- 26
- 31
-
Thanks for the quick response. The example which you used is the one which I am working on. What I am doing is, created a class, with constructor having parameters endpoint and the client proxy. In the appcontext.xml, pass endpoint depending on environment, using a map, like
– Ritesh Mengji Jun 08 '11 at 20:41 -
Great answer! I just have one follow up question. Isn't the lib folder made for libraries? Isn't there a different location that can be accessed from the classpath, such as conf or something? Thanks! – Giovanni Botta Aug 30 '13 at 14:06
-
1Doing some more research, I think the lib folder is actually [the worst place to put configuration](http://www.mulesoft.com/tomcat-classpath) – Giovanni Botta Aug 30 '13 at 14:15
-
It's not the best choice, and not just for Tomcat. I've recently been looking into ZooKeeper (see: http://stackoverflow.com/questions/9940476/zookeeper-for-java-spring-config) but until Spring / JavaEE introduce support for dynamic properties, most solutions will always be a bit of a hack. – Pavel Aug 31 '13 at 16:57
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.

- 23,147
- 2
- 29
- 24
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.

- 2,118
- 14
- 23
One way would be to look at the System.getProperty(key) method, which is pure java. However, this is probably not a great idea since you shouldn't really be doing environment logic of this sort in your application.
Another method would be server configuration (configure a different application context file for each environment's server).
Spring 3.1 is also bringing in new methods to do this sort of thing 'properly' with interchangeable property files. You should take a look at the unified property management blog. There is more detail in the m1 release announcement.

- 4,375
- 1
- 21
- 18