首先引入相关依赖,只列出了核心部分
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
接下来是具体的实现步骤。
1. 创建线程共享工具
保证数据源在同一线程下切换后不被其他线程修改,所以我们将数据源信息保存在ThreadLocal中共享。
package com.myfund.wxapplet.confignew;
/**
* 动态数据源持有者,负责利用ThreadLocal存取数据源名称
*
* @author: haocheng
* @date: 2019-06-11 15:32
*
*/
public class DynamicDataSourceHolder {
//本地线程共享对象
private static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<>();
public static void putDataSouce(String name){
THREAD_LOCAL.set(name);
}
public static String getDataSource(){
return THREAD_LOCAL.get();
}
public static void removeDataSource(){
THREAD_LOCAL.remove();
}
}
2. 实现动态数据源——AbstractRoutingDataSource
spring为我们提供了AbstractRoutingDataSource,即带路由的数据源。继承后我们需要实现它的determineCurrentLookupKey(),该方法用于自定义实际数据源名称的路由选择方法,由于我们将信息保存到了ThreadLocal中,所以只需要从中拿出来即可
package com.myfund.wxapplet.confignew;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源实现类
*
* @author: haocheng
* @date: 2019-06-11 15:36
*
*/
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
//数据源路由,此方用于产生要选取的数据源逻辑名称
@Override
protected Object determineCurrentLookupKey() {
//从线程共享中获取数据源名称
return DynamicDataSourceHolder.getDataSource();
}
}
3. 自定义方法注解——数据源切换
我们切换数据源时,一般都是在调用mapper或service接口的方法前实现,所以我们定义一个方法注解,当AOP检测到方法上有该注解时,根据注解中value对应的名称进行切换。
package com.myfund.wxapplet.confignew