基于Spring的AOP切面编程切换数据源
1、实现Spring提供的获取数据源的抽象类
package com.banksteel.finance.bill.db;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
*
* @description: 动态数据源,动态获取数据源的实现
* @projectName:banksteel-finance-voucher-service
* @author: zhongwen
* @createTime:2017年12月12日 上午10:49:17
*/
public class DynamicDataSource extends AbstractRoutingDataSource
{
private static final Logger log = LoggerFactory.getLogger(DynamicDataSource.class);
/**
* 用户返回当且切换到的数据库
*/
@Override
protected Object determineCurrentLookupKey()
{
//DynamicDataSourceHolder有获取和设置当前数据库的方法get & put
String dataSource = DynamicDataSourceHolder.getDataSource();
log.info("数据库访问获取数据源:{}", dataSource);
return DynamicDataSourceHolder.getDataSource();
}
}
2、一个用来存放threadLocal来保存当前线程的数据源的工具类
package com.banksteel.finance.bill.db;
/**
*
* @description: 动态数据源holder
* @projectName:banksteel-finance-voucher-service
* @author: zhongwen
* @createTime:2017年12月12日 上午10:47:38
*/
public class DynamicDataSourceHolder
{
public static final ThreadLocal<String> HOLDER = new ThreadLocal<String>();
public static void putDataSource(String name)
{
HOLDER.set(name);
}
public static String getDataSource()
{
return HOLDER.get();
}
public static void clearCustomerType() {
HOLDER.remove();
}
}
3、定义一个切面AOP实现类
@Pointcut用于来描述切点
@Before扫描切面执行被切方法之前的操作【切换到注解指定的数据源】
@After被切方法执行完毕后需要将其使用的数据源清空
package com.banksteel.finance.bill.db;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @description 数据库切面
* @className DataSourceAspect
* @projectName banksteel-finance-payable-base-service-provider
* @author fangsy
* @createTime 2018年9月5日上午10:53:55
* @version 1.0.0
*/
@Aspect
@Component
public class DataSourceAspect
{
private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
@Pointcut("execution(* com.banksteel.finance.bill.dao.*.*(..))")
private void aspectPoint(){
//定义一个切入点
}
/**
*
*
* @param joinPoint
* 切点
*/
@Before("aspectPoint()")
public void doBefore(JoinPoint point)
{
Object target = point.getTarget();
String method = point.getSignature().getName();
Class<?>[] classz = target.getClass().getInterfaces();
Class<?