前言 : 都说手动切换数据源比较傻,其实手动切换更好更清晰,注解方式有可能会出现意外情况;当然注解方式比较简洁,具体使用哪种方式,看个人喜欢吧!
一.配置多数据源映射关系
<!-- spring 配置文件的配置多数源映射关系,默认为SQLserver数据源 -->
<bean id="dataSourceExchange" class="com.lexiaotong.www.aspect.DataSourceAspect"/>
<bean class="com.lexiaotong.www.aspect.DynamicDataSource" id="dataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSource_SQLserver" key="dataSource_SQLserver"></entry>
<entry value-ref="dataSource_pgsql" key="dataSource01"></entry>
<entry value-ref="dataSource_pgsql2" key="dataSource02"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource01l"></property>
</bean>
二 . 使用aop切入在实现层切入
<!-- aop切入点-->
<aop:config>
<aop:aspect ref="dataSourceExchange">
<!-- 拦截所有mapper方法 -->
<aop:pointcut id="dataSourcePointcut" expression="execution(* com.weixiaobao.www.service.*.*(..))"/>
<aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
</aop:aspect>
</aop:config>
<!--激活自动代理-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
三 . 定义 DataSourceAspect 类切换数据源
public class DataSourceAspect {
/*注解切换数据源*/
public void intercept(JoinPoint point) throws Exception {
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
}
private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
DataSource source =null;
// 默认使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
source = clazz.getAnnotation(DataSource.class);
DataSourceContextHolder.setDataSource(source.value());
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
source = m.getAnnotation(DataSource.class);
DataSourceContextHolder.setDataSource(source.value());
}
} catch (Exception e) {
}
}
}
四 . 定义DataSourceContextHolder 类 set 和 remove数据源(手动注入数据源)
public class DataSourceContextHolder {
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static void clearDataSource() {
contextHolder.remove();
}
}
五. 注解方式
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource
String value();
}
调用方式: 在方法上添加注解 @DataSource(“数据源”)
如需纯手动配置方式访问: https://blog.csdn.net/qq_42826164/article/details/87657300