springboot aop整合多数据源处理

springboot aop整合多数据源

通过aop进行切面整理

设置默认数据源 :DataSource 这个值可以是任意名称,其实就是声明一个注解,用在方法体上进行数据源切换操作

/**
 * 〈一句话功能简述〉<br> 
 * 〈声明数据源注解〉
 *
 * @create 2020/4/13
 * @since 1.0.0
 */
@Target({ElementType.METHOD})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
    String name() default "";
}
/**
 * 〈一句话功能简述〉<br> 
 * 〈设置默认数据源〉
 *
 * @create 2020/4/13
 * @since 1.0.0
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 默认数据源
     */
    public static final String DEFAULT_DS = "primaryDataSource";
    /**
     * 本地线程共享对象
     */
    private static final ThreadLocal<String> THREAD_LOCAL = new ThreadLocal<>();

    public static void putDataSource(String name){
        THREAD_LOCAL.set(name);
    }
    public static String getDataSource() {
        return THREAD_LOCAL.get();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSource.getDataSource();
    }
    /**
     * 清除本线程使用的数据源,使用默认数据源
     */
    public static void clear() {
        THREAD_LOCAL.remove();
    }
}

设置数据源切面

/**
 * 〈一句话功能简述〉<br> 
 * 〈数据源切面〉
 *
 * @create 2020/4/13
 * @since 1.0.0
 */
@Component
@Aspect
public class DataSourceAspect implements Ordered {
	//这里就是通过aop切到项目数据源的位置(com.xxxx.springbootstudy.config.DataSource.DataSource,这个地址根据自己地址来)
    @Pointcut("@annotation(com.xxxx.springbootstudy.config.DataSource.DataSource)")
    public void pointCut() {
    }
	
    @Before("pointCut()")
    public void annotationPointCutBefore(JoinPoint joinPoint){
        //从切面获取访问得方法
        Class<?> aClass = joinPoint.getTarget().getClass();
        //从切面获取访问方法名称
        String className = joinPoint.getSignature().getName();
        //获取方法得参数类型
        Class[] argClass = ((MethodSignature)joinPoint.getSignature()).getParameterTypes();
        //获取默认数据源
        String defaultDs = DynamicDataSource.DEFAULT_DS;
        try {
            //获得访问的方法对象
            Method  method = aClass.getMethod(className, argClass);
            /**
		     * 判断是否存在@DataSource注解(isAnnotationPresent 这个方法是通过判断b是否在a中,
		     * 指的是指定 注解是否在此元素上,这里是**method**中是否存在**@DataSource**注解)
		     */
      
            if (method.isAnnotationPresent(DataSource.class)){
            	//getAnnotation  如果存在这样的注解,则返回指定类型的元素的注解,否则返回null
                DataSource annotation = method.getAnnotation(DataSource.class);
                //获取所得数据源名称
                 defaultDs = annotation.name();
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        // 切换数据源
        DynamicDataSource.putDataSource(defaultDs);
    }

    /**
     * 在切面之后进行数据源的清除,使用默认数据源
     * @param joinPoint
     */
    @After("pointCut()")
    public void annotationMethodAfter(JoinPoint joinPoint){
        DynamicDataSource.clear();
    }

    /**
     * 其实就是order注解,数越大,优先级越靠后
     * @return
     */
    @Override
    public int getOrder() {
        return 1;
    }
}
/**
 * 〈一句话功能简述〉<br> 
 * 〈数据源配置〉
 *
 * @create 2020/4/13
 * @since 1.0.0
 */
@Configuration
public class DataSourceConfig {
    /**
     * 声明primaryDataSource数据源,数据源注入bean
     * @return
     */
    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.ds1")
    public javax.sql.DataSource primaryDataSource(){
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * secondDataSource,数据源注入bean
     * @return
     */
    @Bean(name = "secondDataSource")
    @Qualifier("secondDataSource")
    //**spring.datasource.druid.ds2**这个注意别写错了,地址和你的yml中的名称一样就行
    @ConfigurationProperties(prefix = "spring.datasource.druid.ds2")
    public javax.sql.DataSource secondDataSource(){
        return DruidDataSourceBuilder.create().build();
    }


    @Primary
    @Bean
    public DataSource dataSource(){
        DynamicDataSource dataSource=new DynamicDataSource();
        /**
         * 默认数据源
         */
        dataSource.setDefaultTargetDataSource(primaryDataSource());
        /**
         * 配置多数据源
         */
        Map map=new HashMap();
        map.put("primaryDataSource",primaryDataSource());
        map.put("secondDataSource",secondDataSource());
        dataSource.setTargetDataSources(map);
        return dataSource;
    }

    /**
     * 配置@Transactional注解事物
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}

最后贴上项目yml配置
在这里插入图片描述
再贴上pom文件,别的大同小异,前两个切面用,后两个数据源用
在这里插入图片描述
使用方式:
在这里插入图片描述
在这里插入图片描述

最后: 仅供参考,有错欢迎指正,我也是看了好多博客才搞懂

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值