1 编写DataSourceHolder
public class DataSourceHolder {
private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();
/**
* 获取当前线程的数据源路由的key
*/
public static String getKey () {
return threadLocal.get();
}
/**
* 绑定当前线程数据源路由的key
* 使用完成后必须调用removeRouteKey()方法删除
*/
public static void setKey (String key) {
threadLocal.set(key);
}
/**
* 删除与当前线程绑定的数据源路由的key
*/
public static void removeKey () {
threadLocal.remove();
}
}
2 编写MultipleDataSource实现AbstractRoutingDataSource
public class MultipleDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey () {
return DataSourceHolder.getKey();
}
}
3 编写注解 @DataSourceKey
@Target({ElementType.METHOD})
@Retention(RUNTIME)
public @interface DataSourceKey {
String value ();
}
4 编写aop DataSourceAspect拦截注解
@Aspect
@Component
public class DataSourceAspect {
private final Log logger = LogFactory.getLog(this .getClass());
@Around ("@annotation(changeDataSource)" )
public Object aroundAdvice (ProceedingJoinPoint point, DataSourceKey changeDataSource) throws Throwable {
try {
DataSourceHolder.setKey(changeDataSource.value());
return point.proceed();
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
DataSourceHolder.removeKey();
}
return null ;
}
}
5 编写xml
<bean id ="dataSource" class ="com.alibaba.druid.pool.DruidDataSource" init-method ="init" destroy-method ="close" >
<property name ="url" value ="${jdbc.url}" />
<property name ="username" value ="${jdbc.username}" />
<property name ="password" value ="${jdbc.password}" />
<property name ="driverClassName" value ="${jdbc.driver}" />
<property name ="initialSize" value ="1" />
<property name ="minIdle" value ="1" />
<property name ="maxActive" value ="300" />
<property name ="maxWait" value ="60000" />
<property name ="timeBetweenEvictionRunsMillis" value ="60000" />
<property name ="minEvictableIdleTimeMillis" value ="300000" />
<property name ="validationQuery" value ="SELECT 'x' FROM DUAl" />
<property name ="testWhileIdle" value ="true" />
<property name ="testOnBorrow" value ="false" />
<property name ="testOnReturn" value ="false" />
<property name ="poolPreparedStatements" value ="true" />
<property name ="maxPoolPreparedStatementPerConnectionSize" value ="20" />
<property name ="filters" value ="stat" />
</bean >
<bean id ="demo" class ="com.alibaba.druid.pool.DruidDataSource" init-method ="init" destroy-method ="close" >
<property name ="url" value ="${jdbc.url}" />
<property name ="username" value ="goisan_gemini" />
<property name ="password" value ="gemini" />
<property name ="driverClassName" value ="${jdbc.driver}" />
<property name ="initialSize" value ="1" />
<property name ="minIdle" value ="1" />
<property name ="maxActive" value ="300" />
<property name ="maxWait" value ="60000" />
<property name ="timeBetweenEvictionRunsMillis" value ="60000" />
<property name ="minEvictableIdleTimeMillis" value ="300000" />
<property name ="validationQuery" value ="SELECT 'x' FROM DUAl" />
<property name ="testWhileIdle" value ="true" />
<property name ="testOnBorrow" value ="false" />
<property name ="testOnReturn" value ="false" />
<property name ="poolPreparedStatements" value ="true" />
<property name ="maxPoolPreparedStatementPerConnectionSize" value ="20" />
<property name ="filters" value ="stat" />
</bean >
<bean id ="multipleDataSource" class ="com.goisan.sdcenter.dynamicdatasource.MultipleDataSource" lazy-init ="true" >
<property name ="targetDataSources" >
<map key-type ="java.lang.String" >
<entry key ="dataSource" value-ref ="dataSource" />
<entry key ="demo" value-ref ="demo" />
</map >
</property >
<property name ="defaultTargetDataSource" ref ="dataSource" />
</bean >