I\'m trying to figure out how my Spring app can determine where it is deployed and load the appropriate datasource. We have 3 environments...my local, the development server, a
For data sources the easiest way would be to define data sources and let the container manage the connection pooling.
To do so, define a resource reference to the data source in web.xml
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/MyDataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
and reference it in spring as such:
<jee:jndi-lookup
id="dataSource"
jndi-name="jdbc/MyDataSource" />
then you can define the data source in the application server, which means you can change the underlying database. In case of websphere, this would be done through the websphere console. In case of tomcat, it would be done through the Context.xml:
<Context>
...
<Resource name="jdbc/MyDataSource" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="javauser" password="javadude"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/javatest"/>
</Context>
That way you only need to change the context to deploy to development, test and production and don't tie your application to a specific database.
Have a look here: http://blog.jayway.com/2010/10/21/environment-specific-configuration-of-spring-applications/ You can have a default config in your app, and optionally override it with a file in a predefined place on your file system.
Pass a system property to the property placeholder, but include all three files in the WAR:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/resources/properties/${myenv}.datasource.properties</value>
</list>
</property>
</bean>
Two solutions
Have one value instead of three with a generic name and in your build configuration provide a flag which properties file should be copied to that path/filename.
Provide the properties as an VM argument while starting the server like -Ddatasource.properties=c:\config\development.datasource.properties and in your XML config file <value>file:///${datasource.properties} </value>
The other answers here have good ideas in them, but I'm answering because my own approach is something of a combination of the three. First, don't reference properties files of multiple environments directly in your Spring XML. Just work from a single file. Then, using a combination of Spring's <context:property-placeholder>
, <jee:jndi-lookup>
, <util:properties>
, and SpEL, you can easily set up a very flexible configuration.
<context:property-placeholder>
gets wired with the output of the <util:properties>
.<util:properties>
uses SpEL to check for a system property with a given name. If available, it uses that as the location of a properties file to load. If not,<jee:jndi-lookup>
, which tries to do a JDNI lookup for the location. If that also doesn't find anything, thendefault-value
attribute of <jee:jndi-lookup>
.This setup makes it simple to specify a properties file location no matter what environment you're in because of all the options.
I would consider using the Cocoon Spring Configurator, which can be used stand-alone, without the rest of the Cocoon project:
http://cocoon.apache.org/subprojects/configuration/spring-configurator/index.html
I found this blog post really useful to get started:
http://mrhaki.blogspot.com/2009/02/use-spring-configurator-to-support.html