动态切换数据源原理

栏目: Java · 发布时间: 6年前

内容简介:有一种场景,调用ServiceA时,使用A数据源,调用ServiceB时,使用B数据源。在不改变原有代码的情况下,这个如何来实现呢。下面是一种实现方式,供参考:比如在操作com.project.service.goods.GoodsService.java时,key应该设置成goods。这里有个问题是,service类跟数据源是分开的,怎么样才能通知到

动态切换数据源原理

有一种场景,调用ServiceA时,使用A数据源,调用ServiceB时,使用B数据源。在不改变原有代码的情况下,这个如何来实现呢。

下面是一种实现方式,供参考:

  • 将各个数据源用key-value形式保存到map中,如下面这个类:
class RouteDatasource {
	Map<String, Datasource> map = new HashMap<>();
	
	map.push("goods", goodsDatasource);
	map.push("order", orderDatasource);
	
	
	获取Connection
	public Connection getConnection() {
		...
	}

}
  • 在操作某个Service类的时候选择对应的数据源

比如在操作com.project.service.goods.GoodsService.java时,key应该设置成goods。这里有个问题是,service类跟数据源是分开的,怎么样才能通知到

RouteDatasource类使用goods的key呢。

方法简单,使用 ThreadLocal 类,在使用GoodsService类时,ThreadLocal中放入key,然后RouteDatasource类从ThreadLocal中取。

class RouteDatasource {
	Map<String, Datasource> map...
	
	map.push("goods", goodsDatasource);
	map.push("order", orderDatasource);
	
	获取Connection
	public Connection getConnection() {
		String key = ThreadLocal.get();
		Datasource ds = map.get(kay);
		return ds.getConnection();
	}

}

获取key完成了,如何设置key呢?不可能在每次使用前put一下吧。容易出错,代码也不美观。有一种方案是使用spring的AOP方式实现。

AOP可以在执行某个Service方法前做一些操作,那么我们就把设置key的操作放在AOP的before行为中。

大致思路是:判断当前方法所在类的package的名称来区分需要设置哪个key。

比如:com.project.service.goods.GoodsService.save()方法的package,是com.project.service.goods开头

那么AOP代码可以这样写

String methodInfo = ...
if(methodInfo.startWith("com.project.service.goods")) {
	ThreadLocal.set("goods")
}

完整的代码如下:

@Component
@Aspect
public class DynamicDataSourceAspect {
	
	@Before("execution(* com.project.service..*.*(..))")
	public void before(JoinPoint jp) {
		String methodName = jp.getSignature().getDeclaringTypeName();
		if (StringUtils.isBlank(methodName)) {
			return;
		}
		if (methodName.startsWith("com.project.service.goods")) {
			ThreadLocal.set("goods")
		} else if (methodName.startsWith("com.project.service.order")) {
			ThreadLocal.set("order")
		}

	}

}

这样,以后只需要配置DynamicDataSourceAspect类即可。

数据源动态切换,主要思想是通过事先定义好的Key-Value进行动态获取。主要使用了ThreadLocal和Spring AOP方式去串连起来。

spring为我们提供了数据源切换类 org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource ,这个类的作用就是一开始提到的RouteDatasource类。感兴趣的同学可以看下代码,很简单。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

区块链

区块链

(美)梅兰妮·斯万 / 新星出版社 / 2016-1-1 / 50元

本书以全景式的方式介绍了区块链相关技术目前发展状况和未来技术衍生方向的展望,作者认为区块链技术可能是继互联网发明以来最大的技术革命。全书从比特币的概念模型和区块链技术正开始结合的方面讨论了三个不同的结构层面:区块链1.0、2.0和3.0。首先介绍了比特币和区块链技术的基本定义和概念,还有作为区块链1.0应用核心的货币和支付系统。其次,区块链2.0将超越货币范畴,会发展为货币市场和金融应用,类似于合......一起来看看 《区块链》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具