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

摘要:本篇文章的场景是做调度中心和监控中心时的需求,后端使用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配置对应的是原来的

@Bean

public Advisor druidAdvisor() {

DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();

defaultPointcutAdvisor.setPointcut(jdkRegexpMethodPointcut());

defaultPointcutAdvisor.setAdvice(overallQueryInterceptor());

return defaultPointcutAdvisor;

}

}

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

@SwitchDataBase(switch2Backup = true)

List listByTemplateOver3(@Param("templates") List templates);

总结

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

如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值