spring中的方法调用重试机制

一、@Retryable注解

注解方式实现重试机制比较简单,只需要我们在需要重试的方法上加入以下注解

@Retryable(value = {RemoteAccessException.class},    maxAttempts = 3,    backoff = @Backoff(delay = 1000))
  • value:指定需要重试的异常类型。在这个例子中,我们指定了 RemoteAccessException 类型的异常。
  • maxAttempts:指定最大重试次数。在这个例子中,我们指定了最大重试次数为 3。
  • backoff:指定重试之间的时间间隔。在这个例子中,我们指定了 1000 毫秒的时间间隔。

 当然异常类型可以写成Exception.class,这样当方法抛出任何异常都会重试了。

使用注解的方式实现重试机制需要注意以下几点:

1.首先是启动类加上@EnableReTry注解

2. 要求需要重试的方法和调用它的方法不能同属一个类中,因为@Retryable注解是通过切面实现的,说白了就是带有@Retryable注解的方法和调用他的方法都要被spring管理,属于不同的类即可。

3.@Retryable只能实现重试机制,重试次数达到上限后,还是失败,此时如果有需要回调处理的逻辑,需要另外一个注解@Recover

@Retryable(value = {SQLException.class}, maxAttempts = 3, backoff = @Backoff(delay = 100))
public void myMethod() throws SQLException {// Some database operation that may throw a SQLException
}@Recover
public void recover(SQLException e) {// Recovery logic goes here
}

要求@Retryable@Recover必须定义在一个类当中,这一点和上面调用@Retryable的方法必须分属不同的类正好相反,同时也要求@Retryable注解的方法不能有返回值,否则@Recover不生效

那如果一个类中有多个@Recover和@Retryable怎么区分?

很简单,可以通过value属性来区分它们。value属性允许您指定一个异常类型的数组,以区分在方法执行期间抛出的不同异常类型。

具体示例如下:

@Service
public class MyService {
 
    @Retryable(value = {IOException.class})
    public void methodA() throws IOException {
        // Some code that may throw an IOException
    }
 
    @Recover
    public void recoverA(IOException e) {
        // Recovery logic for methodA() goes here
    }
 
    @Retryable(value = {NullPointerException.class})
    public void methodB() throws NullPointerException {
        // Some code that may throw a NullPointerException
    }
 
    @Recover
    public void recoverB(NullPointerException e) {
        // Recovery logic for methodB() goes here
    }
}

笔者不想再单独写类了,想让调用@Retryable注解的方法和带有@Retryable注解本身的方法,两个方法属于一个类中,但是此时@Retryable不生效了,所以搜寻了另外一种方式,通过编码方法实现方法重试,当然也是spring提供的工具了,自己封装也不是不行,就是没那么好,考虑的不全面,请看第二种方式。

二、通过RetryTemplate

这种方式也是要求在启动类上添加@EnableReTry注解,如上图所示

1.RetryTemplate的配置类

package com.ruoyi.maintenance.thirdinterface.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;/*** 重试配置类* @author hulei*/
@Configuration
@EnableRetry
public class RetryConfiguration {@Beanpublic RetryTemplate retryTemplate() {SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();//最大重试次数retryPolicy.setMaxAttempts(5);ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();//倍数backOffPolicy.setMultiplier(2);//初始间隔backOffPolicy.setInitialInterval(3000);RetryTemplate template = new RetryTemplate();template.setRetryPolicy(retryPolicy);template.setBackOffPolicy(backOffPolicy);return template;}
}

配置类主要是设置一些重试次数和重试时间等参数

2.重试代码

我要重试的方法如下图

调用它的方法如下

 引入retryTemplate

 主要代码片段

 try{String result = retryTemplate.execute(//RetryCallback,需要重试的业务逻辑(RetryCallback<String, Throwable>) retryContext -> doPost(url, rsaEncryptHandle(jsonHandle(jsonObject,loop,platform).toJSONString())),//RecoveryCallback兜底,多次重试失败后的处理逻辑,取最后一次重试抛出的异常信息,抛出异常retryContext -> {log.error("删除设备推送接口多次重试调用失败");throw new RuntimeException(retryContext.getLastThrowable().getMessage());});log.info("删除设备远程调用返回结果:{}",result);}catch (Throwable e){log.error("删除远程调用异常:{}",e.getMessage());}

核心是retryTemplate.excute调用

有两个参数RetryCallback和RecoveryCallback

 1.RetryCallback 

包装需要重试的逻辑,比较简单就是调用了我需要重试的方法doPost()

2.RecoveryCallback

重试次数达到上限,任然没有成功时的回调方法

笔者这里只是打印了并抛出了异常信息,如果有其他需要处理的异常回调逻辑,单独写一个方法,在这里调用即可。

总结:两种方式各有好处,看个人选择,如果需要编写的重试方法较多,建议使用注解方式,省时省力,单一场景使用,不想再写过多的类,使用第二种编码的方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/298508.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RHCE9学习指南 第8章 用户管理

8.1 基本概念 用户在操作系统中是非常重要的一块&#xff0c;我们登录系统&#xff0c;访问共享文件夹等都需要用户进行验证。所以&#xff0c;掌握管理用户的知识是非常有必要的。 说到用户&#xff0c;我们会提到两个名词账户信息和木马信息。 账户信息&#xff1a;我们可以…

【技术科普】CPU、GPU、TPU、NPU分别是什么?哪个最强?

技术日新月异&#xff0c;物联网、人工智能、深度学习等遍地开花&#xff0c;各类芯片名词CPU&#xff0c;GPU, TPU, NPU层出不穷…它们都是什么&#xff1f;又有着什么千丝万缕的关系和区别&#xff1f; 接下来&#xff0c;统一介绍一下&#xff1a; 01 CPU CPU最早用于计算…

管理团队的5个策略和技巧,让你的团队更高效

管理团队并非一项简单任务&#xff0c;它需要明确的策略和技巧。首先&#xff0c;要明确团队目标&#xff0c;这是所有管理动作的起点。 没有目标&#xff0c;团队就会迷失方向&#xff0c;越努力越容易偏离轨道。设定目标不仅能让团队和员工明确自己的方向&#xff0c;还能帮…

Java网络爬虫拼接姓氏,名字并写出到txt文件(实现随机取名)

目录 1.爬取百家姓1.爬取代码2.爬取效果 2.爬取名字1.筛选男生名字2.筛选女生名字 3.数据处理&#xff08;去除重复&#xff09;4.拼接数据5.将数据写出到文件中 1.爬取百家姓 目标网站&#xff0c;仅作为实验目的。 ①爬取姓氏网站&#xff1a; https://hanyu.baidu.com/shic…

CentOS7安装Java11

文章目录 Java11下载地址卸载OpenJDK查询原系统安装的 JDK根据原系统安装的 JDK 进行卸载命令修改 安装JDK生成JRE Java11下载地址 https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html 卸载OpenJDK 查询原系统安装的 JDK java -version yum l…

第十四章 集合(Set)

一、Set 接口&#xff08;P518&#xff09; 1. Set 接口基本介绍 &#xff08;1&#xff09;无序&#xff08;添加和取出的顺序不一致&#xff09;&#xff0c;没有索引。 &#xff08;2&#xff09;不允许重复元素&#xff0c;所以最多包含一个 null。 2. Set 接口的常用方法…

docker安装及入门

笔记来自黑马课堂&#xff1a;【黑马程序员Docker快速入门到项目部署&#xff0c;MySQL部署Nginx部署docker自定义镜像DockerCompose项目实战一套搞定-哔哩哔哩】 https://b23.tv/niWEhEF 一、什么是docker&#xff1a; 快速构建、运行、管理应用的工具。--帮助我们快速部署提…

olap/clickhouse-存储

NSM DBMS 将单个元组的几乎所有属性连续地存储在一个页面中。 这种存储是 OLTP 工作负载的理想选择&#xff0c;OLTP 的事务倾向于访问单个实体&#xff0c;并且插入工作的负载比较重。 使用 tuple-at-a-time 的迭代器处理模型。 NSM 数据库页面大小通常是 4KB 硬件页面的某个…

MySql数据库的下载安装及使用教程

MySql数据库的下载安装及使用教程 一、MySql的下载与安装1.MySQL的下载2.MySQL的安装3、Workbench以及mysql的使用 一、MySql的下载与安装 1.MySQL的下载 进入网址&#xff1a;https://www.mysql.com/downloads/并点击图中红圈位置 再次点击图中红圈位置 继续点击红圈位置 …

深入学习Python与Vscode环境的安装与配置

文章目录 前言1. 安装Python2. 配置Python虚拟环境3. 安装Vscode4. 安装Python插件5. 配置Vscode与虚拟环境6. 创建Python项目7. 运行和调试8. 使用扩展功能9. 安装Jupyter支持10. 版本管理与集成11. 自定义配置结语Python技术资源分享1、Python所有方向的学习路线2、学习软件3…

LeetCode刷题--- 字母大小写全排列

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述递归递归、搜索与回…

用CHAT了解更多知识点

问CHAT&#xff1a;什么是硅基生命和碳基生命&#xff1f; CHAT回复&#xff1a;硅基生命和碳基生命是两种理论性的生物体类型&#xff0c;这些生物体主要是由硅或碳元素以及其他元素构成的。 碳基生命是我们当前所熟知的生命形式。碳元素能够形成稳定且复杂的分子&#xff0c;…