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

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重试原理的解析的更多相关文章

  1. 自己动手实践 spring retry 重试框架

    前序 马上过年了,预祝大家,新年快乐,少写bug 什么是spring retry? spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断. 什么时候用? 远程 ...

  2. Spring Retry 重试

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说 ...

  3. spring boot 启动原理详细解析

    我们开发任何一个Spring Boot项目,都会用到如下的启动类 1 @SpringBootApplication 2 public class Application { 3 public stat ...

  4. spring retry 重试机制完整例子

    public static Boolean vpmsRetryCoupon(final String userId) { // 构建重试模板实例 RetryTemplate retryTemplate ...

  5. spring容器IOC原理解析

    原理简单介绍: Spring容器的原理,其实就是通过解析xml文件,或取到用户配置的bean,然后通过反射将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这些bean ...

  6. Spring异常重试框架Spring Retry

    Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...

  7. Spring IOC设计原理解析:本文乃学习整理参考而来

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  8. Spring Boot启动原理解析

    Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置 ...

  9. 这一次搞懂Spring自定义标签以及注解解析原理

    前言 在上一篇文章中分析了Spring是如何解析默认标签的,并封装为BeanDefinition注册到缓存中,这一篇就来看看对于像context这种自定义标签是如何解析的.同时我们常用的注解如:@Se ...

随机推荐

  1. 【书评:Oracle查询优化改写】第四章

    [书评:Oracle查询优化改写]第四章 BLOG文档结构图 一.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① check的 ...

  2. Sleep和 SleepEx函数

    Sleep和 SleepEx函数的功能是在指定的执行时间内中止所在线程的执行. SleepEx扩展了Sleep的功能,在最短超时时间间隔已到的情况下恢复线程执行外,在以下两种情况下发生时也可以恢复执行 ...

  3. UML——从类图到C++

    简易软件开发流程 实践中,use case and description.class diagram与sequence diagram三者搭配,几乎是UML项目的基本类型,所以在分工或外包的设计文档 ...

  4. springboot 2.2.1默认跳到登录页

    最新的springboot 2.2.1版本,启动之后访问http://localhost:8080 会直接跳转到默认登录页,是由于springboot默认配置了安全策略,在启动类中忽略该配置即可 在启 ...

  5. 快排算法Java版-每次以最左边的值为基准值手写QuickSort

    如题 手写一份快排算法. 注意, 两边双向找值的时候, 先从最右边起找严格小于基准值的值,再从最左边查找严格大于基准base的值; 并且先右后左的顺序不能反!!这个bug改了好久,233~ https ...

  6. Android init介绍(下)

    上一篇请参考<Android init介绍(上)> 5. AIL 在init启动过程中,系统服务等均是通过解析rc文件来启动,而rc文件则是由Android初始化语言(Android In ...

  7. Python基础初始之二

    1.格式化的输出 当你遇到这样的需要:字符串中想让某些位置变成动态可传入的,首先考虑用格式化输出 1.格式化输出:% 2. 格式化输出:format 3. 格式化输出:f 2.运算符 3.编码 待续

  8. AFL Fuzz安装及完成一次简单的模糊测试

    关于AFL fuzz AFL fuzz是一个模糊测试工具,它封装了一个GCC/CLang编译器,用于对被测代码重新编译的过程中进行插桩.插桩完毕后,AFL fuzz就可以给其编译过的代码输入不同的参数 ...

  9. linux /lib64/libc.so.6: version `GLIBC_2.17′ not found

    使用root权限安装Glances,需要用到glibc,安装失败后所有命令都不好用了,执行回报“/lib64/libc.so.6: version `GLIBC_2.17′ not found ”的错 ...

  10. Codeforces1114F Please, another Queries on Array?

    题目链接:http://codeforces.com/problemset/problem/1114/F 题意:序列$a$,有两种操作,1 区间里的数同时乘上$x$ 2 求区间的积的欧拉函数 线段树好 ...