java 重试_Java重试机制修改
最近无意间看到了一段代码,实话实说看的我有点难受,刚开始的时候还略微有点懵,只是感觉代码很长。等我捋了一遍之后,发现是一段调用远程接口,失败进行重试功能的代码。代码如下:
image.png
方法用到了递归,在重试次数小于零跳出。
说一下存在的问题吧:
接口重试和业务本身不发生关系,所以具有很高的耦合性
方法采用递归实现,有栈溢出的风险
重试逻辑无法进行重用
可配置性比较低
看下怎么改一下:
-抽离出重试代码,预留接口,业务代码填入,抽离工具类如下:
public abstract class MyRetryTemplate {
//重试次数
private int retryTime;
//重试时间
private int sleepTime;
//是否倍数增长
private boolean multiple = false;
/**
* 执行业务方法逻辑,由实现类实现
*
* @return
*/
public abstract T remote() throws Exception;
public T execute() throws InterruptedException {
for (int i = 1; i < retryTime + 1; i++) {
try {
return remote();
} catch (Exception e) {
System.out.println(e.getMessage());
if (multiple){
Thread.sleep(sleepTime);
}
else{
Thread.sleep(sleepTime * (i));
}
}
}
return null;
}
public T submit(ExecutorService executorService) {
Future submit = executorService.submit((Callable) () -> execute());
try {
return (T) submit.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return null;
}
public MyRetryTemplate setRetryTime(int retryTime) {
this.retryTime = retryTime;
return this;
}
public MyRetryTemplate setSleepTime(int sleepTime) {
this.sleepTime = sleepTime;
return this;
}
public MyRetryTemplate setMultiple(boolean multiple) {
this.multiple = multiple;
return this;
}
}
上面的类中,值定义了重试的次数,间隔的时间,和时间的增长参数,预留了remote()抽象方法,交由具体的实现类来实现。类中使用了泛型,支持返回不同的对象。并且支持同步和异步调用。
看下修改后的代码,如下:
image.png
是不是感觉一下清爽了很多,这里重试相关的参数,我直接写死在了代码中,可以通过配置文件和数据库配置引入。这个方法应该还能精简,最后两句感觉还是有点多余,由于不知道是干啥的, 就暂且留在这吧。
修改后的代码,虽然解决了一些上面的问题,但是并没有完全解决,代码的侵入性,上面已经说了既然这是重试的逻辑,就不应该出现在代码中。有没有解决的办法呢,有,切面。
下面看下通过切面该怎么实现。
首先定义一个注解:
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {
int count() default 0 ;
long sleep() default 0 ;
}
定义切面
@Aspect
@Component
public class RetryAspect {
ExecutorService executorService = Executors.newFixedThreadPool(3);
@Around(value = "@annotation(Retry)")
public Object execute(ProceedingJoinPoint point, Retry retry) throws InterruptedException {
System.out.println("----------------- Aspect ---------------------");
MyRetryTemplate myRetryTemplate = new MyRetryTemplate() {
@Override
public ParametersHolder remote() throws Throwable {
return (ParametersHolder) point.proceed();
}
}.setRetryTime(3).setSleepTime(10000).submit(executorService);
return submit;
}
}
最终实现:
image.png
在注解中,添加自定义的参数,便可以实现零侵入,也更容易实现方法的复用,如果有其他的业务需要实现重试,直接在业务方法上添加注解即可。
如果不想用这种方法,也可以借助第三方工具guava-retrying和 spring-retry 来实现此功能。
java 重试_Java重试机制修改相关推荐
- java 反射 修改字段_Java反射机制-修改字段值
需要用到的类: Field 需要用到的方法: getDeclaredField(); getField(); setAccessible(); 需要用到的字段: public int a=5; pub ...
- java内省_java内省机制
一.内省是什么.实现方式: 内省(Introspector)是Java语言对Bean类属性.事件的一种缺省处理方法. 例如类A中有属性name,那我们可以通过getName,setName来得到其值或 ...
- java万法_Java内省机制和 BeanUtils实现
内省(Introspector) Java 语言对 Bean 类属性.事件的一种缺省处理方法. 例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的 ...
- java 可见_Java可见性机制的原理
基本概念 1.可见性 当一个线程修改了共享变量时,另一个线程可以读取到这个修改后的值. 2.内存屏障(Memory Barriers) 处理器的一组指令,用于实现对内存操作的顺序限制. 3.缓冲行 C ...
- foxmail邮件加载失败重试_java retry(重试) spring retry, guava retrying 详解
系列说明 java retry 的一步步实现机制. java-retry 源码地址 情景导入 简单的需求 产品经理:实现一个按条件,查询用户信息的服务. 小明:好的.没问题. 代码 UserServi ...
- java 深拷贝_java 深拷贝与浅拷贝机制详解
java 深拷贝与浅拷贝机制详解 概要: 在Java中,拷贝分为深拷贝和浅拷贝两种.java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定 ...
- java f反射_java反射机制
反射定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- java反射机制详解_JAVA反射机制详解_JSP/Java编程_互联网开发技术网_传播最新的编程技术_php361.com...
今天,下午在和朋友聊天的时候,聊起了反射这个话题. 我们就从下面这个段简单的代码开始吧. 这个代码输出什么,想必大部分的读者跟我一样,会很快地知道答案:0 1 2 3 4 5 6 7 8 9.事实也是 ...
- java异常处理代码详解_Java异常处理机制总结
概念介绍 异常是发生在程序执行过程中阻碍程序正常执行的错误事件,当一个程序出现错误时,可能的情况有如下3种: 语法错误 代码的格式错了,某个字母输错了 运行时错误 空指针异常,数组越界,除数为零等 逻 ...
最新文章
- 转:MySQL 开发实践 8 问,你能 hold 住几个?
- java classname.this_java 中 类名.this与类名.class
- 我们应该使用什么指标来描述数据中心及其效率?
- (转)iOS 6的Rotation--详细版本
- Java——集合转数组并对其进行遍历
- python doc_2019-2020年Python3中文教程完整版.doc
- 两个电脑如何切换以方便使用文件
- Android Jetpack 之 ViewModel
- 如何把电脑文件传到虚拟机
- 3842开关电源完整原理图_8大常见开关电源电路分析,让你项目设计更轻松!
- Docker到底是什么?为什么它这么火!
- 软件GUI测试中的关注点
- Improving Opencv10 More Morphology Transformations
- 一款云迁移产品的成长史
- VS2013 安装及问题解决
- lcx的使用-内网穿透
- 搜狗输入法安装上问题
- 计算机网络基础——CS架构与BS架构、OSI七层协议、tcp/ip五层模型讲解
- 22 个最常用的 Python 包
- Git 中 cat 的使用
热门文章
- RxJava 2.0的基本使用
- 你真正的去了解过Linux吗?不单单是一些命令操作,比如它的系统架构!!!
- java线程----生产者和消费者问题
- 数据结构: 试用判定树的方法给出在中序线索化二叉树上: (1) 如何搜索指定结点的在中序下的后继。 (2) 如何搜索指定结点的在前序下的后继。(3) 如何搜索指定结点的在后序下的后继。
- 【Docker】Docker操作常用命令
- 【JavaWeb】Response请求转发与重定向辨析
- 【计组实验】P3 Verilog多周期处理器开发 MIPS指令集
- JDK 14的新特性:instanceof模式匹配
- Redis学习之Sentinel(四)
- JUC锁-Semaphore(八)