Spring 动态切换数据源
主要利用Spring AOP面向切面实现,AbstractRoutingDataSource动态数据源切换的重点
-
引入Aop相关jar包
<dependency> <groupId>aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.12.RELEASE</version> </dependency>
-
在applicationContex.xml中配置两套数据源
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${driverClass}"/> <property name="jdbcUrl" value="${jdbcUrl}"/> <property name="user" value="${user}"/> </bean> <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${driverClass2}"/> <property name="jdbcUrl" value="${jdbcUrl2}"/> <property name="user" value="${user2}"/> </bean> //注入dataSource <bean id="dataSource" class="realfunc.aspect.MultipleDataSource"> <property name="defaultTargetDataSource" ref="dataSource1"></property> <property name="targetDataSources"> <map key-type="realfunc.aspect.DataSources"> <entry key="master" value-ref="dataSource1"></entry> <entry key="slave" value-ref="dataSource2"></entry> </map> </property> </bean>
3.代码实现
//声明多套数据库
public enum DataSources{
master,slave
}
public class DataSourceTypeManager{
public static final ThreadLocal<DataSource> dataSourceType = new ThreadLocal<DataSource>(){
@Override
protected DataSource initialValue(){
return DataSources.master;
}
}
public static DataSources get(){
return dataSourceTypes.get();
}
public static void set(DataSources dataSourceType){
dataSourceTypes.set(dataSourceType);
}
public static void reset(){
dataSourceTypes.set(DataSources.master);
}
}
//实现多数据源切换
public class MultipleDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
return DataSourceTypeManager.get();
}
}
//切面 对特定包下的方法进行数据源切换
@Aspect
@Component
@Order(0)
public class DataSourceAspect {
//此处也可以使用注解 因为我项目中 不同的数据库放在相同的包下面 所以直接声明到包
@Before("execution(* realfunc.service.linkTrace.*.*(..))")
public void doBefore(JoinPoint joinPoint){
DataSourceTypeManager.set(DataSources.slave);
}
}
也可以使用注解声明,在切面声明中对注解进行切入点声明。
public @interface dataSourceName(){
String value default "master";
}