自己定制spring 数据源

本文介绍了一种通过配置属性实现Spring中DataSource从JDBC驱动到JNDI查找方式自动切换的方法,简化了部署过程。

原文链接地址:http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1933350

最近在做项目,开发时是通过driver创建datasource的,配置如下
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="${dataSource.driverClassName}" />

    <property name="url" value="${dataSource.url}" />

    <property name="username" value="${dataSource.username}" />

    <property name="password" value="${dataSource.password}" />

</bean>
实施时是通过jndi查找得到datasource,配置如下:
 
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">

    <property name="jndiName" value="${dataSource.jndiName}" />

</bean>
其中属性文件是通过propertyConfigurer导入的:
 
<bean id="propertyConfigurer" 

    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"

    dependency-check="none">

    <property name="fileEncoding" value="UTF-8" />

    <property name="locations">

        <list>

            <value>classpath:spring-app.properties</value>

        </list>

    </property>

</bean>
属性 文件的内容如下:
dataSource.jndiName=jdbc/myDataSource

dataSource.driverClassName=oracle.jdbc.driver.OracleDriver

dataSource.url=jdbc:oracle:thin:@localhost:1521:myServId

dataSource.username=myUser

dataSource.password=myPassword

  采用上面这种方式,在每次部署的时候都要修改applicationContext.xml的dataSource配置,有点麻烦 通过学习 JndiObjectFactoryBean 的代码,自己写了一个数据源的工厂类:
package laochake.spring.datasource;

import javax.naming.NamingException;

import javax.sql.DataSource;

import org.springframework.beans.factory.FactoryBean;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.jdbc.datasource.DriverManagerDataSource;

import org.springframework.jndi.JndiLocatorSupport;

import org.springframework.util.StringUtils;

/**

* 数据源工厂bean,通过 jndi 属性判断是从jndi取得数据源还是用jdbc驱动创建数据源<br>

* 设计此类的目的是简化部署时的配置,即只同过设置定jndi的值就可以自动切换数据源的获取方式

* @author laochake

* @since 2007-12-13 下午01:26:46

*/

public class DataSourceFactoryBean implements FactoryBean,InitializingBean {

  

/**缓存数据源对象*/

private DataSource dataSource;

/**是否jndi数据源*/

private boolean jndi;

/**数据源的名字(如果是jndi数据源)*/

private String jndiName;

/**jdbc驱动类(非jndi的情况)*/

private String driverClassName;

/**数据库的url(非jndi的情况)*/

private String url;

/**用户名(非jndi的情况)*/

private String username;

/**密码(非jndi的情况)*/

private String password;



//TODO:此处省略了属性的set方法



/**

* 初始化

* @author laochake

* @since 2007-12-13 下午01:48:03

* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()

*/

public void afterPropertiesSet() throws Exception {

   if(this.isJndi()){

    if (!StringUtils.hasText(this.jndiName)) {

     throw new IllegalArgumentException("jndiName is required");

    }

   }else{

    if (!StringUtils.hasText(this.driverClassName)) {

     throw new IllegalArgumentException("driverClassName is required");

    }

    if (!StringUtils.hasText(this.url)) {

     throw new IllegalArgumentException("url is required");

    }

    if (!StringUtils.hasText(this.username)) {

     throw new IllegalArgumentException("username is required");

    }

    if (!StringUtils.hasText(this.password)) {

     throw new IllegalArgumentException("password is required");

    }

   }

   //在初始化时就创建数据源

   this.createDataSource();

}

/**

* 实现 FactoryBean 的方法,取得对象

* @author laochake

* @since 2007-12-13 下午01:33:35

* @see org.springframework.beans.factory.FactoryBean#getObject()

*/

public Object getObject() {

   DataSource ds = this.createDataSource();

   return ds;

}



/**

* 创建数据源对象,并保存到 this.dataSource属性

* @author laochake

* @since 2007-12-13 下午01:46:44

* @return

*/

protected DataSource createDataSource(){

   DataSource ds = this.dataSource;

   if(ds==null){

    try{

     if(this.isJndi()){

      ds = new JndiDataSourceSupport().lookupDataSource(this.jndiName);

     }else{

      ds=new DriverManagerDataSource(driverClassName, url, username, password);

     }

    }catch(Throwable err){

     throw new RuntimeException(err);

    }

   }

   this.dataSource=ds;

   return ds;

}

/**

* 实现 FactoryBean 的方法,取得工厂创建的对象类型

* @author laochake

* @since 2007-12-13 下午01:42:57

* @see org.springframework.beans.factory.FactoryBean#getObjectType()

*/

public Class getObjectType() {

   return javax.sql.DataSource.class;

}



/**

* 实现 FactoryBean 的方法,是否单例模式(始终返回true)

* @author laochake

* @since 2007-12-13 下午01:43:29

* @see org.springframework.beans.factory.FactoryBean#isSingleton()

*/

public boolean isSingleton() {

   return true;

}

/**

* jndi数据源查找类(内部私有类)

* @author laochake

* @since 2007-12-13 下午01:49:09

*/

private class JndiDataSourceSupport extends JndiLocatorSupport{

   public DataSource lookupDataSource(String jndiName) throws NamingException{

    return (DataSource)super.lookup(jndiName, javax.sql.DataSource.class);

   }

}



}

  使用以上定义类,新的dataSource定义方式如下:
<bean id="dataSource" class="com.gdcn.spring.datasource.DataSourceFactoryBean">

    <description><![CDATA[ 数据源定义 ]]></description>

    <property name="jndi" value="${dataSource.IS_JNDI}" />

    <property name="jndiName" value="${dataSource.jndiName}" />

    <property name="driverClassName" value="${dataSource.driverClassName}" />

    <property name="url" value="${dataSource.url}" />

    <property name="username" value="${dataSource.username}" />

    <property name="password" value="${dataSource.password}" />

</bean>
修改后的属性 文件的内容如下:
dataSource.IS_JNDI=true

dataSource.jndiName=jdbc/myDataSource

dataSource.driverClassName=oracle.jdbc.driver.OracleDriver

dataSource.url=jdbc:oracle:thin:@localhost:1521:myServId

dataSource.username=myUser

dataSource.password=myPassword
  
  在部署应用时,如果使用jdbc驱动创建数据源,则IS_JNDI=false 如果使用jndi查找得到数据源,则IS_JNDI=true。
  可见第二种方式的配置简单了很多,只通过修改dataSource.IS_JNDI就能实现 datasource获取方式的切换。
 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值