Spring AbstractRoutingDataSource抽象类剖析

来源:互联网 发布:python ascii计算 编辑:程序博客网 时间:2024/06/11 07:05

1、扩展Spring的AbstractRoutingDataSource抽象类(该类充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上。)
从AbstractRoutingDataSource的源码中:

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean

我们可以看到,它继承了AbstractDataSource,而AbstractDataSource不就是javax.sql.DataSource的子类,So我们可以分析下它的getConnection方法:

public Connection getConnection() throws SQLException {      return determineTargetDataSource().getConnection();  }  public Connection getConnection(String username, String password) throws SQLException {       return determineTargetDataSource().getConnection(username, password);  }

获取连接的方法中,重点是determineTargetDataSource()方法,看源码:

    /**      * Retrieve the current target DataSource. Determines the      * {@link #determineCurrentLookupKey() current lookup key}, performs      * a lookup in the {@link #setTargetDataSources targetDataSources} map,      * falls back to the specified      * {@link #setDefaultTargetDataSource default target DataSource} if necessary.      * @see #determineCurrentLookupKey()      */      protected DataSource determineTargetDataSource() {          Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");          Object lookupKey = determineCurrentLookupKey();          DataSource dataSource = this.resolvedDataSources.get(lookupKey);          if (dataSource == null && (this.lenientFallback || lookupKey == null)) {              dataSource = this.resolvedDefaultDataSource;          }          if (dataSource == null) {              throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");          }          return dataSource;      }

上面这段源码的重点在于determineCurrentLookupKey()方法,这是AbstractRoutingDataSource类中的一个抽象方法,而它的返回值是你所要用的数据源dataSource的key值,有了这个key值,resolvedDataSource(这是个map,由配置文件中设置好后存入的)就从中取出对应的DataSource,如果找不到,就用配置默认的数据源。
2、看完源码,应该有点启发了吧,没错!你要扩展AbstractRoutingDataSource类,并重写其中的determineCurrentLookupKey()方法,来实现数据源的切换:

package com.datasource.test.util.database;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/** * 获取数据源(依赖于spring) * @author linhy */public class DynamicDataSource extends AbstractRoutingDataSource{    @Override    protected Object determineCurrentLookupKey() {        return DataSourceHolder.getDataSource();    }}

DataSourceHolder这个类则是我们自己封装的对数据源进行操作的类:

package com.datasource.test.util.database;/** * 数据源操作 * @author linhy */public class DataSourceHolder {    //线程本地环境    private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();    //设置数据源    public static void setDataSource(String customerType) {        dataSources.set(customerType);    }    //获取数据源    public static String getDataSource() {        return (String) dataSources.get();    }    //清除数据源    public static void clearDataSource() {        dataSources.remove();    }}
阅读全文
0 0
原创粉丝点击