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>