Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring datasource configuration for localhost, development, and production

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, and the production server. So far I have 3 properties files called

localhost.datasource.properties
development.datasource.properties
production.datasource.properties

I have them conifgured like this:

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:/resources/properties/production.datasource.properties</value>
                <value>classpath:/resources/properties/development.datasource.properties</value>
                <value>classpath:/resources/properties/localhost.datasource.properties</value>
            </list>
        </property>
    </bean>

    <bean id="dataSourceMySQL" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
        p:driverClassName="${mysql.jdbc.driver.class.name}"
        p:url="${mysql.jdbc.url}"
        p:username="${mysql.jdbc.username}"
        p:password="${mysql.jdbc.password}" />

</beans>

This works fine when I am on my localhost machine. If I deploy a war file to development it is still reading the localhost properties since it is last in the list and I get an error. What is the best way to implement this?

Thanks

like image 579
blong824 Avatar asked Aug 25 '11 19:08

blong824


3 Answers

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.

like image 99
beny23 Avatar answered Oct 20 '22 18:10

beny23


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>
like image 4
atrain Avatar answered Oct 20 '22 20:10

atrain


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.

like image 2
Buhb Avatar answered Oct 20 '22 20:10

Buhb