012 spring retry重试原理的解析

2022-10-29,,,,

  有点复杂,在后续的章节,将会对其中涉及到的知识点,再分章节进行说明。

1.程序结构

  

2.@Retryable

package com.jun.web.annotation.theory;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retryable {
int maxAttemps() default 0;
}

3.RetryService

package com.jun.web.annotation.theory;

public interface RetryServcie {
void testRetry();
}

4.RetryServiceImpl

package com.jun.web.annotation.theory;

public class RetryServcieImpl implements RetryServcie {
private int count=5;
@Override
@Retryable(maxAttemps = 5)
public void testRetry() {
System.out.println("这是第"+count+"执行方法");
throw new RuntimeException();
}
}

5.拦截器

MethodInterceptor接口被用来拦截指定的方法,对方法进行增强
具体的是哪个方法,将会通过Enhancer说明
package com.jun.web.annotation.theory;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; //MethodInterceptor接口被用来拦截指定的方法,对方法进行增强
public class AnnotationRetryInterceptor implements MethodInterceptor {
private int times=0;
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//obj是代理后的子类 ,method是调用方法 ,args是方法入参 , proxy是MethodProxy代理对象
//获取拦截方法中的注解
Retryable retryable = method.getAnnotation(Retryable.class);
if(retryable==null){
return methodProxy.invokeSuper(o, objects);
}else{
int maxAttemps = retryable.maxAttemps();
try {
return methodProxy.invokeSuper(o,objects);
}catch (Throwable t){
if (times++ == maxAttemps){
System.out.println("已经达到最大值:"+times);
}else {
System.out.println("调用"+method.getName()+"方法异常,开始第"+times+"次重试");
methodProxy.invoke(o,objects);
}
}
}
return null;
}
}

6.代理

package com.jun.web.annotation.theory;

import org.springframework.cglib.proxy.Enhancer;

public class RetryProxy {
public Object newProxyInstance(Object target){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(new AnnotationRetryInterceptor());
return enhancer.create();
}
}

7.测试

package com.jun.web.annotation.theory;

public class RetryHandler {
public static void main(String[] args) {
RetryServcieImpl retryServcieImpl = new RetryServcieImpl();
RetryProxy retryProxy = new RetryProxy();
//
RetryServcie retryServcie = (RetryServcie) retryProxy.newProxyInstance(retryServcieImpl);
retryServcie.testRetry();
}
}

8.效果

Connected to the target VM, address: '127.0.0.1:59161', transport: 'socket'
这是第5执行方法
调用testRetry方法异常,开始第1次重试
这是第5执行方法
调用testRetry方法异常,开始第2次重试
这是第5执行方法
调用testRetry方法异常,开始第3次重试
这是第5执行方法
调用testRetry方法异常,开始第4次重试
这是第5执行方法
调用testRetry方法异常,开始第5次重试
这是第5执行方法
已经达到最大值:6
Disconnected from the target VM, address: '127.0.0.1:59161', transport: 'socket'

012 spring retry重试原理解析的相关教程结束。

《012 spring retry重试原理的解析.doc》

下载本文的Word格式文档,以方便收藏与打印。