利用Spring的AbstractRoutingDataSource解决多数据源的问题

来源:互联网 发布:网站代备案 知乎 编辑:程序博客网 时间:2024/06/05 08:43

多数据源的配置在项目中应用比较多,我这里只列举示例.

  1. 在公司项目中运用了元注解的方式对其进行注解.
import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)public @interface DataSource { String value();}

2.对元注解进行操作,这里又设置了一个类,为了方便切换源数据吧,看注释吧!

    public class DataSourceAspect {    /**     * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源     *      * @param point     * @throws Exception     */    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());    }    /**     * 提取目标对象方法注解和类型注解中的数据源标识     *      * @param clazz     * @param method     */    private void resolveDataSource(Class<?> clazz, Method method) {        try {            DynamicDataSourceHolder.setDataSource("dataSourceA");            Class<?>[] types = method.getParameterTypes();            // 默认使用类型注解            if (clazz.isAnnotationPresent(DataSource.class)) {                DataSource source = clazz.getAnnotation(DataSource.class);                DynamicDataSourceHolder.setDataSource(source.value());            }            // 方法注解可以覆盖类型注解            Method m = clazz.getMethod(method.getName(), types);            if (m != null && m.isAnnotationPresent(DataSource.class)) {                DataSource source = m.getAnnotation(DataSource.class);                DynamicDataSourceHolder.setDataSource(source.value());            }        } catch (Exception e) {            System.out.println(clazz + ":" + e.getMessage());        }    }    }

3.写一个类用继承abstractRoutingDataSource,并重写determineCurrentLookupKey方法.

public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        // 从自定义的位置获取数据源标识        return DynamicDataSourceHolder.getDataSource();    }    }

4.利用ThreadLocal解决线程安全问题

    public class DynamicDataSourceHolder {    /**     * 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰     */    private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>();    public static String getDataSource() {        return THREAD_DATA_SOURCE.get();    }
  public static void setDataSource(String dataSource) {        THREAD_DATA_SOURCE.set(dataSource);    }    public static void clearDataSource() {        THREAD_DATA_SOURCE.remove();    }    }

好.ok了.

0 0