内容简介:有一种场景,调用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类。感兴趣的同学可以看下代码,很简单。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Nature of Code
Daniel Shiffman / The Nature of Code / 2012-12-13 / GBP 19.95
How can we capture the unpredictable evolutionary and emergent properties of nature in software? How can understanding the mathematical principles behind our physical world help us to create digital w......一起来看看 《The Nature of Code》 这本书的介绍吧!