• 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'
  • 相关阅读:
    Linux九阴真经之催心掌残卷5(正则表达式)
    Linux九阴真经之催心掌残卷4(grep文本处理 )
    Linux九阴真经之催心掌残卷3
    Linux九阴真经之催心掌残卷2
    0.1.kubeadm快速部署kubernetes
    0.2.kubeadm搭建kubernetes高可用集群(CentOS)
    Nginx——模块(1)
    Nginx——主配置段
    Nginx——安装
    Nginx——I/O模型
  • 原文地址:https://www.cnblogs.com/juncaoit/p/11399991.html
Copyright © 2020-2023  润新知