Spring Boot中自定义注解结合AOP实现主备库切换问题
摘要:本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的压力,在本篇文章中主要记录在SpringBoot中通过自定义注解结合AOP实现直接连接备库查询。
一.通过AOP自定义注解实现主库到备库的切换
1.1自定义注解
自定义注解如下代码所示
importjava.lang.annotation.ElementType;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
importjava.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public@interfaceSwitchDataBase{
booleanswitch2Backup()defaultfalse;
}
1.2实现方法拦截器对自定义注解处理
importjava.lang.reflect.Method;
importjava.util.Arrays;
importorg.aopalliance.intercept.MethodInterceptor;
importorg.aopalliance.intercept.MethodInvocation;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.stereotype.Component;
/**
*处理走备库逻辑的注解
*/
@Component
publicclassSwitchDataBaseInterceptorimplementsMethodInterceptor{
privatefinalLoggerlog=LoggerFactory.getLogger(SwitchDataBaseInterceptor.class);
@Override
publicObjectinvoke(MethodInvocationinvocation)throwsThrowable{
Methodmethod=invocation.getMethod();
SwitchDataBaseannotation=getAnnotation(method);
if(annotation==null){
returninvocation.proceed();
}
Objectval=null;
if(!ThreadLocalMap.containsKey(GroupDataSourceRouteHelper.DATASOURCE_INDEX)){
if(annotation.switch2Backup()){
log.info("querybackupDB,method:"+method.getName());
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(1,true);
}else{
log.info("queryprimaryDB,method:"+method.getName());
GroupDataSourceRouteHelper.executeByGroupDataSourceIndex(0,true);
}
}
try{
val=invocation.proceed();
}catch(Exceptione){
log.info(method.getDeclaringClass().getName()+"."+
invocation.getMethod().getName()+"方法调用失败,arguments:"+
Arrays.toString(invocation.getArguments()));
thrownewRuntimeException(e);
}finally{
GroupDataSourceRouteHelper.removeGroupDataSourceIndex();
}
returnval;
}
/**
*找方法上面声明的注解
*/
privateSwitchDataBasegetAnnotation(Methodmethod){
if(method.isAnnotationPresent(SwitchDataBase.class)){
returnmethod.getAnnotation(SwitchDataBase.class);
}
returnnull;
}
}
1.3配置OverallQueryConfiguration
在SpringBoot中装配AOPBean,实现扫描特定目录下的注解,实现切面变成形成通知处理。示例代码如下
importcom.wdk.wms.annotation.SwitchDataBaseInterceptor;
importorg.springframework.aop.Advisor;
importorg.springframework.aop.support.DefaultPointcutAdvisor;
importorg.springframework.aop.support.JdkRegexpMethodPointcut;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
@Configuration
publicclassSwitchDataBaseConfiguration{
@Bean(name="overallQueryInterceptor")
publicSwitchDataBaseInterceptoroverallQueryInterceptor(){
returnnewSwitchDataBaseInterceptor();
}
//添加aop的pointcut
@Bean(name="jdkRegexpMethodPointcut")
publicJdkRegexpMethodPointcutjdkRegexpMethodPointcut(){
JdkRegexpMethodPointcutjdkRegexpMethodPointcut=newJdkRegexpMethodPointcut();
jdkRegexpMethodPointcut.setPatterns("com.wdk.wms.mapper.*");
returnjdkRegexpMethodPointcut;
}
//设置默认的aop配置对应的是原来的
@Bean
publicAdvisordruidAdvisor(){
DefaultPointcutAdvisordefaultPointcutAdvisor=newDefaultPointcutAdvisor();
defaultPointcutAdvisor.setPointcut(jdkRegexpMethodPointcut());
defaultPointcutAdvisor.setAdvice(overallQueryInterceptor());
returndefaultPointcutAdvisor;
}
}
1.4如何使用注解从主库到备库的切换
@SwitchDataBase(switch2Backup=true) ListlistByTemplateOver3(@Param("templates")List templates);
总结
以上所述是小编给大家介绍的SpringBoot中自定义注解结合AOP实现主备库切换,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!