I use the JNDI approach. I bound a java.util.Properties object into our app server's JNDI tree, configuring it from a properties file located outside of the war file. The specifics on how to do this depend on your application server.
For different environments, you'd just use a different properties file. The JNDI object is configured and bound at app-server startup.
This properties JNDI object can be accessed by your app directly via JNDI, or given to a PropertyPlaceHolderConfigurer like so:
Code:
<bean id="propertyResourceConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties"><ref local="config" /></property>
</bean>
<bean id="config" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"><value>config/Properties</value></property>
<property name="resourceRef"><value>true</value></property>
</bean>
where "config/Properties" is the JNDI name defined in web.xml and mapped in the appserver-specific web xml file.
Then you can configure your beans by using ${property} throughout your application context as mentioned by other posters.
Tim