012 spring retry重试原理的解析

时间:2019-08-23
本文章向大家介绍012 spring retry重试原理的解析,主要包括012 spring retry重试原理的解析使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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

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'

原文地址:https://www.cnblogs.com/juncaoit/p/11399991.html