您的位置:首页 > 编程语言 > Java开发

spring retry重试机制原理解析(手写原理)

2018-07-28 01:30 543 查看
springboot 整合spring retry : https://my.oschina.net/wangjunBlog/blog/1889015

手写spring retry注解

注解实现:

package com.wj.project.api.common.retry.annotation;

import java.lang.annotation.*;
/**
* @Auther: wangjun
* @Date: 2018/7/28
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retryable {

int maxAttemps() default 0;
}

添加拦截器:

package com.wj.project.api.common.retry.interceptor;

import com.wj.project.api.common.retry.annotation.Retryable;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
* @Auther: wangjun
* @Date: 2018/7/28 00:24
*/
public class AnnotationAwareRetryOperationsInterceptor implements MethodInterceptor {

//记录重试次数
private int times = 0;

@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//获取拦截的方法中的Retryable 注解
Retryable retryable = method.getAnnotation(Retryable.class);
if (retryable == null) {
return methodProxy.invokeSuper(o, objects);
} else {
//有Retryable注解
int maxAttemps = retryable.maxAttemps();
try {
return methodProxy.invokeSuper(o, objects);
} catch (Throwable e) {
if (times++ == maxAttemps) {
System.out.println("已达到最大重试次数:" + maxAttemps + " , 不再重试");
} else {
System.out.println("调用 " + method.getName() + "方法异常,开始第 " + times + "次重试");
//注意这里不是 invokeSuper 方法,invokeSuper会退出当前interceptor的处理
methodProxy.invoke(o, objects);
}
}
}
return null;
}
}

使用cglib动态代理 :

package com.wj.project.api.common.retry.Proxy;

import com.wj.project.api.common.retry.interceptor.AnnotationAwareRetryOperationsInterceptor;
import org.springframework.cglib.proxy.Enhancer;

/**
* @Auther: wangjun
* @Date: 2018/7/28 00:39
*/
public class RetryProxy {

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

demo测试:

/**
* @Auther: wangjun
* @Date: 2018/7/28 00:48
*/
public interface RetryService {
void testRetry();
}

package com.wj.project.api.attempt.Retry;

import com.wj.project.api.common.retry.annotation.Retryable;

/**
* @Auther: wangjun
* @Date: 2018/7/28 00:35
*/
public class RetryServiceImpl implements RetryService{

private int count = 0;

@Retryable(maxAttemps = 5)
public void testRetry() {
System.out.println("这是第 :" + count + "次执行方法");
throw new RuntimeException();
}

}


package com.wj.project.api.attempt.Retry;

import com.wj.project.api.common.retry.Proxy.RetryProxy;

/**
* @Auther: wangjun
* @Date: 2018/7/28 00:45
*/
public class RetryHandler {

public static void main(String[] args) {

RetryServiceImpl retryServiceImpl = new RetryServiceImpl();
RetryProxy retryProxy = new RetryProxy();
//创建代理类
RetryService retryService =(RetryService)retryProxy.newProxyInstance(retryServiceImpl);
retryService.testRetry();
}
}

测试结果:

"E:\Program Files\Java\jdk1.8.0_65\bin\java.exe" "-javaagent:E:\Program Files\JetBrains\IntelliJ IDEA 2018.1.6\lib\idea_rt.jar=55570:E:\Program Files\JetBrains\IntelliJ IDEA 2018.1.6\bin" -Dfile.encoding=UTF-8 -classpath "E:\Program Files\Java\jdk1.8.0_65\jre\lib\charsets.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\deploy.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\access-bridge-64.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\cldrdata.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\dnsns.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\jaccess.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\jfxrt.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\localedata.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\nashorn.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunec.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunjce_provider.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunmscapi.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\sunpkcs11.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\ext\zipfs.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\javaws.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\jce.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\jfr.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\jfxswt.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\jsse.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\management-agent.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\plugin.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\resources.jar;E:\Program Files\Java\jdk1.8.0_65\jre\lib\rt.jar;E:\dev\dev-dianrong\wj-springboot-core\wj-api\target\classes;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot-starter-web\2.0.3.RELEASE\spring-boot-starter-web-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot-starter\2.0.3.RELEASE\spring-boot-starter-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot\2.0.3.RELEASE\spring-boot-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot-autoconfigure\2.0.3.RELEASE\spring-boot-autoconfigure-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot-starter-logging\2.0.3.RELEASE\spring-boot-starter-logging-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;E:\jar\apache-maven-repo2\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;E:\jar\apache-maven-repo2\org\apache\logging\log4j\log4j-to-slf4j\2.10.0\log4j-to-slf4j-2.10.0.jar;E:\jar\apache-maven-repo2\org\apache\logging\log4j\log4j-api\2.10.0\log4j-api-2.10.0.jar;E:\jar\apache-maven-repo2\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;E:\jar\apache-maven-repo2\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;E:\jar\apache-maven-repo2\org\yaml\snakeyaml\1.19\snakeyaml-1.19.jar;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot-starter-json\2.0.3.RELEASE\spring-boot-starter-json-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\com\fasterxml\jackson\core\jackson-databind\2.9.6\jackson-databind-2.9.6.jar;E:\jar\apache-maven-repo2\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;E:\jar\apache-maven-repo2\com\fasterxml\jackson\core\jackson-core\2.9.6\jackson-core-2.9.6.jar;E:\jar\apache-maven-repo2\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.6\jackson-datatype-jdk8-2.9.6.jar;E:\jar\apache-maven-repo2\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.6\jackson-datatype-jsr310-2.9.6.jar;E:\jar\apache-maven-repo2\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.6\jackson-module-parameter-names-2.9.6.jar;E:\jar\apache-maven-repo2\org\springframework\boot\spring-boot-starter-tomcat\2.0.3.RELEASE\spring-boot-starter-tomcat-2.0.3.RELEASE.jar;E:\jar\apache-maven-repo2\org\apache\tomcat\embed\tomcat-embed-core\8.5.31\tomcat-embed-core-8.5.31.jar;E:\jar\apache-maven-repo2\org\apache\tomcat\embed\tomcat-embed-el\8.5.31\tomcat-embed-el-8.5.31.jar;E:\jar\apache-maven-repo2\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.31\tomcat-embed-websocket-8.5.31.jar;E:\jar\apache-maven-repo2\org\hibernate\validator\hibernate-validator\6.0.10.Final\hibernate-validator-6.0.10.Final.jar;E:\jar\apache-maven-repo2\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;E:\jar\apache-maven-repo2\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;E:\jar\apache-maven-repo2\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;E:\jar\apache-maven-repo2\org\springframework\spring-web\5.0.7.RELEASE\spring-web-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-beans\5.0.7.RELEASE\spring-beans-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-webmvc\5.0.7.RELEASE\spring-webmvc-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-aop\5.0.7.RELEASE\spring-aop-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-context\5.0.7.RELEASE\spring-context-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-expression\5.0.7.RELEASE\spring-expression-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\retry\spring-retry\1.2.2.RELEASE\spring-retry-1.2.2.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-core\5.0.7.RELEASE\spring-core-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\springframework\spring-jcl\5.0.7.RELEASE\spring-jcl-5.0.7.RELEASE.jar;E:\jar\apache-maven-repo2\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar" com.wj.project.api.attempt.Retry.RetryHandler
这是第 :0次执行方法
调用 testRetry方法异常,开始第 1次重试
这是第 :0次执行方法
调用 testRetry方法异常,开始第 2次重试
这是第 :0次执行方法
调用 testRetry方法异常,开始第 3次重试
这是第 :0次执行方法
调用 testRetry方法异常,开始第 4次重试
这是第 :0次执行方法
调用 testRetry方法异常,开始第 5次重试
这是第 :0次执行方法
已达到最大重试次数:5 , 不再重试

Process finished with exit code 0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Spring-Retry Spring