基于 Guava Retry 在Spring封装一个重试功能
pom依赖
<dependency><groupId>com.github.rholder</groupId><artifactId>guava-retrying</artifactId><version>2.0.0</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
注解类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retryable {/*** 需要重试的异常类型* this.isAssignableFrom(方法抛出的异常) 也就是说,方法抛出的异常必须是retryOn的子类或者子接口*/Class<? extends Throwable> retryOn() default Throwable.class;// 重试次数int maxAttempts() default 3;// 重试间隔long delayMillis() default 1000;
}
import com.github.rholder.retry.RetryException;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Component
@Aspect
@Order(1)
public class RetryableAspect {@Around("@annotation(retryable)")public Object retry(ProceedingJoinPoint joinPoint, Retryable retryable) throws Throwable {Retryer<Object> retryer = RetryerBuilder.<Object>newBuilder().retryIfExceptionOfType(retryable.retryOn()).withStopStrategy(StopStrategies.stopAfterAttempt(retryable.maxAttempts())).withWaitStrategy(WaitStrategies.fixedWait(retryable.delayMillis(), TimeUnit.MILLISECONDS)).build();try {return retryer.call(() -> {try {return joinPoint.proceed();} catch (Exception exception) {throw exception;} catch (Throwable e) {throw new WrapRetryThrowable(e);}});} catch (RetryException e) {throw e.getLastFailedAttempt().getExceptionCause();}}public static class WrapRetryThrowable extends Exception {public WrapRetryThrowable(Throwable cause) {super(cause);}}}
测试类
在这里插入代码片@RestController
public class RetryController {/*** 顶级异常类测试* @return* @throws Throwable*/@Retryable(retryOn = Exception.class,maxAttempts = 3,delayMillis = 1000)@GetMapping("/throwable")public String performTask() throws Throwable {System.out.println("performTask" + System.currentTimeMillis());// 在这里实现可能抛出异常的业务逻辑throw new Throwable("error");}/*** 异常类测试* @return* @throws CustomException*/@Retryable(retryOn = CustomException.class,maxAttempts = 2,delayMillis = 1000)@GetMapping("/customException")public void customException() {System.out.println("customException" + System.currentTimeMillis());// 在这里实现可能抛出异常的业务逻辑}// 抛出的异常跟枚举异常不一致,不会重试@Retryable(retryOn = CustomException.class,maxAttempts = 3,delayMillis = 1000)@GetMapping("/customException2")public String customException2() throws Exception {System.out.println("customException2" + System.currentTimeMillis());// 在这里实现可能抛出异常的业务逻辑throw new Exception("这是一段自定义异常的抛出");}}
相关文章:
基于 Guava Retry 在Spring封装一个重试功能
pom依赖 <dependency><groupId>com.github.rholder</groupId><artifactId>guava-retrying</artifactId><version>2.0.0</version> </dependency> <dependency><groupId>org.springframework.boot</groupId>…...

适用HarmonyOS 3.1版本及以上的应用及服务开发工具 DevEco Studio 3.1.1 Release 安装
文章目录 安装步骤1.下载安装包2.安装成功后,初次运行studio2.1 配置node与ohpm的环境2.2安装sdk2.3等待安装结束 3.创建项目3.1 点击Create Project3.2 选择一个空项目3.3 项目配置3.4 Finish、等待依赖下载完毕3.5 项目创建完成 tip 提示4.配置运行环境4.1 真机运…...

[信号与系统系列] 正弦振幅调制之差拍信号
当将具有不同频率的两个正弦曲线相乘时,可以创建一个有趣的音频效果,称为差拍音符。这种现象听起来像颤音,最好通过选择一个频率非常小的信号与和另一个频率大约1KHz的信号,把二者混合从而听到。一些乐器能够自然产生差拍音符。使…...
vb+SQL航空公司管理系统设计与实现
航空公司管理信息系统 一个正常营运的航空公司需要管理所拥有的飞机、航线的设置、客户的信息等,更重要的还要提供票务管理。面对各种不同种类的信息,需要合理的数据库结构来保存数据信息以及有效的程序结构支持各种数据操作的执行。 本设计讲述如何建立一个航空公司管理信…...
python爬取网页视频
Python是一种功能强大的编程语言,被广泛应用于网络爬虫、数据分析和人工智能等领域。在网络爬虫中,常常需要从网页中获取视频或者录制网页视频。下面将介绍如何使用Python来录制网页视频。 import time from selenium import webdriver # 创建驱动程序 d…...

数据挖掘具体步骤
数据挖掘具体步骤 1、理解业务与数据 2、准备数据 数据清洗: 缺失值处理: 异常值: 数据标准化: 特征选择: 数据采样处理: 3、数据建模 分类问题: 聚类问题: 回归问题 关联分析 集成学习 image B…...
react class与hooks区别
在React中,有两种主要的方式来管理组件的状态和生命周期:Class 组件和 Hooks。 Class 组件: Class 组件是 React 最早引入的方式,它是基于 ES6 class 的语法来创建的。Class 组件包含了生命周期方法,可以用来处理组件…...
Python爬虫思维:异常处理与日志记录
作为一名专业的爬虫代理供应商,我们经常会看见各种各样的爬虫异常情况。网络请求超时、页面结构变化、反爬虫机制拦截等问题时常出现在客户的工作中。 在这篇文章中,我将和大家分享一些关于异常处理与日志记录的思维方法。通过合理的异常处理和有效的日志…...

(十六)大数据实战——安装使用mysql版的hive服务
前言 hive默认使用的是内嵌据库derby,Derby 是一个嵌入式数据库,可以轻松地以库的形式集成到应用程序中。它不需要独立的服务器进程,所有的数据存储在应用程序所在的文件系统中。为了支持hive服务更方便的使用,我们使用mysql数据…...

【信号生成器】从 Excel 数据文件创建 Simulink 信号生成器块研究(Simulink)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

【UE4 RTS】01-Camera SetUp
UE版本:4.24.3 前言 本篇主要完成游戏模式、玩家控制器和玩家控制的Pawn的设置,下一篇介绍如何实现Pawn的移动 步骤 1. 首先创建一个俯视角游戏模板 2. 首先删除“TopDownCharacter”, 3. 新建一个文件夹命名为“RTS_Toturial” 在文件夹…...

Mirror网络库 | 说明
此篇为上文,下篇:Mirror网络库 | 实战 一、介绍 基于UNET,从2014年经过9年实战测试;服务器和客户端是一个项目;使用NetworkBehaviour而不是MonoBehaviour,还有NetworkServer和NetworkClient;Mi…...
分布式异步任务处理组件(九)
最近完成了网络通信模块的一些基本代码实现,这里记录一些关于类和接口设计的问题和思考;另外进度可能会受阻,之前不知道猴年马月投的简历现在开始邀约面试了,包括今天在内的三天都有一场面试--主要是今天中午的面试过后两分钟HR就…...

[excel]vlookup函数对相同的ip进行关联
一、需求(由于ip不可泄漏所以简化如下) 有两个sheet: 找到sheet1在sheet2中存在的ip,也就是找到有漏洞的ip 二、实现 vlookup函数有4个参数 第一个:当前表要匹配的列,选择第一个sheet当前行需要处理的ip即可 第二个:第二个shee…...

两个状态的马尔可夫链
手动推导如下公式。 证明: 首先将如下矩阵对角化: { 1 − a a b 1 − b } \begin {Bmatrix} 1-a & a \\ b & 1-b \end {Bmatrix} {1−aba1−b} (1)求如下矩阵的特征值: { 1 − a a b 1 − b } { x 1 x 2 } λ { x 1 x 2 }…...

SpringBoot 依赖管理
Spring Boot 依赖管理 1. 父项目做依赖管理 无需关注版本号,自动版本仲裁机制 <!-- 依赖管理 --> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version&g…...

重试框架入门:Spring-RetryGuava-Retry
前言 在日常工作中,随着业务日渐庞大,不可避免的涉及到调用远程服务,但是远程服务的健壮性和网络稳定性都是不可控因素,因此,我们需要考虑合适的重试机制去处理这些问题,最基础的方式就是手动重试…...
[QCM6125][Android13] 修复PRODUCT_COPY_FILES无法拷贝so
文章目录 开发平台基本信息问题描述解决方法 开发平台基本信息 芯片: QCM6125 版本: Android 13 kernel: msm-4.14 问题描述 在进行系统移植时,经常会把一些自己开发的c或者c程序编译成so库,然后在系统服务中去调用这些库。所以在进行新代码开发时&am…...

微服务Eureka注册中心
目录 一、Eureka的结构和作用 二、搭建eureka-server 三、服务注册 四、服务发现 假如我们的服务提供者user-service部署了多个实例,如图: 存在的问题: order-service在发起远程调用的时候,该如何得知user-service实例的ip地址…...

Java:企业级java后端开发,需要掌握哪些内容
一、什么是后端开发 后端开发是指开发基于服务器端的软件应用程序,也称为系统的后台或服务器端编程。 后端程序员负责处理网站或应用程序后台的逻辑和功能,包括数据库管理、服务器端脚本编写、API设计、数据安全性、网站性能优化等。 后端开发技术通常包…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...