通过AbstractRoutingDataSource实现动态数据源

项目中用到了动态数据源,所以在这里做下记录。

 

AbstractRoutingDataSource中route是路由的意思,单从名字,我们就可以看出这个类是做什么用的

 

动态数据源是指,同一个数据库访问接口,根据上下文不通,可以利用不同的数据源访问数据库。 项目中采用了spring jdbc来访问数据库,配置文件如下:

 

<!--sqlMapClient配置-->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
         <property name="dataSource" ref="dataSource" />
         <property name="configLocation"      value="xxxxxx" />
</bean>

<!--数据源配置-->
<bean id="dataSource" class="继承类AbstractRoutingDataSource">
	<property name="targetDataSources">
		<!--配置多个数据源-->	
	</property>
</bean>

 spring中提供了类AbstractRoutingDataSource来实现动态数据源,这个类实现了DataSource接口,getConnection()方法如下:

 

public Connection getConnection() throws SQLException {
	return determineTargetDataSource().getConnection();
}

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;
}

 在getConnection方法中又调用了方法determineTargetDataSource,在这个方法中,只是返回一个数据源对象,但是返回哪个数据源对象呢,玄机在Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());

这行代码,我们可以在自己的实现类中去定制这个方法,根据自己的要求来确定具体返回哪一个数据源对象

 

每一次DAO接口调用,都会有一个线程上下文,我可以把需要使用哪一个数据源的信息放到线程变量中,然后再AbstractRoutingDataSource的实现类中,我可以像下面那样重写determineCurrentLookupKey方法

private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    
 @Override
 protected Object determineCurrentLookupKey() {
        return contextHolder.get();
 }

 这样每个线程间相互隔离,也不会担心线程安全问题

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值