1.首先创建自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyRetry {
//重试次数,默认三次
int value() default 3;
//定义触发重试的异常
Class<? extends Exception> exception() default Exception.class;
//定义降级处理方法
String recover() default "";
}
2.编写aop处理代码:
(1)定义切面:
@Configuration
@Aspect
public class ExceptionConfig {
@Pointcut(value = "@annotation(MyRetry))")
public void pointT() {
}
(2)编写环绕切面处理方法:
@Around(value = "pointT()")
public Object t(ProceedingJoinPoint point) throws Throwable {
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Method method = methodSignature.getMethod();
//获得方法注解
MyRetry annotation = method.getAnnotation(MyRetry.class);
//定义初始执行方法次数
int flag = 0;
//执行方法
return retry(point, flag, annotation);
}
(3)编写重试处理方法:
public Object retry(ProceedingJoinPoint point, int flag, MyRetry annotation) throws Exception {
try {
System.out.println("执行方法次数:" + flag);
return point.proceed();
} catch (Throwable e) {
//捕获异常,判断是否进行重试
flag++;
if (annotation.exception().isAssignableFrom(e.getClass())) {
//判断重试次数是否超出
if (flag <= annotation.value()) {
return this.retry(point, flag, annotation);
} else {
//超出次数选择降级处理
return this.recover(point, annotation.recover());
}
}
}
return null;
}
public Object recover(ProceedingJoinPoint point, String recover) throws Exception {
if (StringUtils.isBlank(recover)) {
return null;
}
Method method = point.getTarget().getClass().getDeclaredMethod(recover);
return method.invoke(point.getTarget());
}
3.实际中测试~
@RestController
public class TestController {
@MyRetry(value = 1, exception = Exception.class, recover = "recover")
@GetMapping("test")
public Object test() {
if (1 == 1) {
throw new RuntimeException();
}
return "";
}
public Object recover() {
return "降级处理";
}
}
控制台打印:
执行方法次数:0
执行方法次数:1
前端返回:
"降级处理"