Spring Boot中自定义注解结合AOP实现主备库切换问题

 更新时间:2019年08月02日 09:50:03   作者:alterem  
这篇文章主要介绍了Spring Boot中自定义注解+AOP实现主备库切换的相关知识,本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需要的朋友可以参考下

摘要:本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的压力,在本篇文章中主要记录在Spring Boot中通过自定义注解结合AOP实现直接连接备库查询。

一.通过AOP 自定义注解实现主库到备库的切换

1.1 自定义注解

自定义注解如下代码所示

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SwitchDataBase {
  boolean switch2Backup() default false;
}

1.2 实现方法拦截器对自定义注解处理

import java.lang.reflect.Method;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
 * 处理走备库逻辑的注解
 */
@Component
public class SwitchDataBaseInterceptor implements MethodInterceptor {
  private final Logger log = LoggerFactory.getLogger(SwitchDataBaseInterceptor.class);
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    Method method = invocation.getMethod();
    SwitchDataBase annotation = getAnnotation(method);
    if (annotation == null) {
      return invocation.proceed();
    }
    Object val = null;
    if(!ThreadLocalMap.containsKey(GroupDataSourceRouteHelper.DATASOURCE_INDEX)) {
      if (annotation.switch2Backup()) {
        log.info("query back up DB, method: " + method.getName());
        GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(1, true);
      } else {
        log.info("query primary DB, method: " + method.getName());
        GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0, true);
      }
    }
    try {
      val = invocation.proceed();
    } catch (Exception e) {
      log.info(method.getDeclaringClass().getName() + "." +
          invocation.getMethod().getName() + "方法调用失败,arguments:" +
          Arrays.toString(invocation.getArguments()));
      throw new RuntimeException(e);
    } finally {
      GroupDataSourceRouteHelper.removeGroupDataSourceIndex();
    }
    return val;
  }
  /**
   * 找方法上面声明的注解
   */
  private SwitchDataBase getAnnotation(Method method) {
    if (method.isAnnotationPresent(SwitchDataBase.class)) {
      return method.getAnnotation(SwitchDataBase.class);
    }
    return null;
  }
}

1.3 配置OverallQueryConfiguration

在Spring Boot中装配AOP Bean,实现扫描特定目录下的注解,实现切面变成形成通知处理。示例代码如下

import com.wdk.wms.annotation.SwitchDataBaseInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwitchDataBaseConfiguration {
  @Bean(name = "overallQueryInterceptor")
  public SwitchDataBaseInterceptor overallQueryInterceptor() {
    return new SwitchDataBaseInterceptor();
  }
  //添加aop的pointcut
  @Bean(name = "jdkRegexpMethodPointcut")
  public JdkRegexpMethodPointcut jdkRegexpMethodPointcut() {
    JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut();
    jdkRegexpMethodPointcut.setPatterns("com.wdk.wms.mapper.*");
    return jdkRegexpMethodPointcut;
  }
  //设置默认的aop配置对应的是原来的<aop:advisor>
  @Bean
  public Advisor druidAdvisor() {
    DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
    defaultPointcutAdvisor.setPointcut(jdkRegexpMethodPointcut());
    defaultPointcutAdvisor.setAdvice(overallQueryInterceptor());
    return defaultPointcutAdvisor;
  }
}

1.4 如何使用注解从主库到备库的切换

@SwitchDataBase(switch2Backup = true)
List<ConsumerNoticeMsg> listByTemplateOver3(@Param("templates") List<Integer> templates);

总结

以上所述是小编给大家介绍的Spring Boot中自定义注解结合AOP实现主备库切换,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

相关文章

  • Java 获取当前时间及实现时间倒计时功能【推荐】

    Java 获取当前时间及实现时间倒计时功能【推荐】

    这篇文章主要介绍了Java 获取当前时间及实现时间倒计时功能 ,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-05-05
  • Spring Cloud整合XXL-Job的示例代码

    Spring Cloud整合XXL-Job的示例代码

    这篇文章主要介绍了springcloud整合xxl-job的示例代码,主要分为四个过程,本文给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • Java学习之缓冲流的原理详解

    Java学习之缓冲流的原理详解

    为了提高其数据的读写效率,Java中又定义了四种缓冲流,分别是:字节缓冲输入流、字节缓冲输出流、字符缓冲输入流和字符缓冲输出流。本文主要来和大家聊聊这些缓冲流的原理,希望对大家有所帮助
    2023-01-01
  • Mybatis实现动态SQL编写详细代码示例

    Mybatis实现动态SQL编写详细代码示例

    这篇文章主要为大家详细介绍了Mybatis中动态SQL的编写使用,动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题,感兴趣想要详细了解可以参考下文
    2023-05-05
  • Java多线程中的ReentrantLock可中断锁详细解读

    Java多线程中的ReentrantLock可中断锁详细解读

    这篇文章主要介绍了Java多线程中的ReentrantLock可中断锁详细解读,ReentrantLock中的lockInterruptibly()方法使得线程可以在被阻塞时响应中断,比如一个线程t1通过lockInterruptibly()方法获取到一个可重入锁,并执行一个长时间的任务,需要的朋友可以参考下
    2023-12-12
  • Java基于解释器模式实现定义一种简单的语言功能示例

    Java基于解释器模式实现定义一种简单的语言功能示例

    这篇文章主要介绍了Java基于解释器模式实现定义一种简单的语言功能,简单描述了解释器模式的概念、功能及Java使用解释器模式定义一种简单语言的相关实现与使用技巧,需要的朋友可以参考下
    2018-05-05
  • Mybatis中SqlMapper配置的扩展与应用详细介绍(1)

    Mybatis中SqlMapper配置的扩展与应用详细介绍(1)

    这篇文章主要介绍了Mybatis中SqlMapper配置的扩展与应用(1)的相关资料,非常不错具有参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • Java 中POI 导入EXCEL2003 和EXCEL2007的实现方法

    Java 中POI 导入EXCEL2003 和EXCEL2007的实现方法

    这篇文章主要介绍了Java 中POI 导入EXCEL2003 和EXCEL2007的实现方法的相关资料,希望通过本文大家能掌握理解这种方法,需要的朋友可以参考下
    2017-09-09
  • @RequestMapping对不同参数的接收方式示例详解

    @RequestMapping对不同参数的接收方式示例详解

    Spring MVC框架中,@RequestMapping注解用于映射URL到控制器方法,不同的参数类型如简单参数、实体参数、数组参数、集合参数、日期参数和JSON参数,本文给大家介绍@RequestMapping对不同参数的接收方式,感兴趣的朋友一起看看吧
    2024-10-10
  • SpringBoot项目中新增脱敏功能的实例代码

    SpringBoot项目中新增脱敏功能的实例代码

    项目中,由于使用端有两个,对于两个端的数据权限并不一样。Web端可以查看所有数据,小程序端只能查看脱敏后的数据,这篇文章主要介绍了SpringBoot项目中新增脱敏功能,需要的朋友可以参考下
    2022-11-11

最新评论