0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一个Spring注解轻松搞定循环重试功能!

jf_ro2CN3Fa 来源:芋道源码 2023-04-24 11:43 次阅读

731ecf3c-df3e-11ed-bfe3-dac502259ad0.jpg

前言

在实际工作中,重处理是一个非常常见的场景,比如:

  • 发送消息失败。
  • 调用远程服务失败。
  • 争抢锁失败。

这些错误可能是因为网络波动造成的,等待过后重处理就能成功。通常来说,会用try/catchwhile循环之类的语法来进行重处理,但是这样的做法缺乏统一性,并且不是很方便,要多写很多代码。然而spring-retry却可以通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

@Retryable是什么?

spring系列的spring-retry是另一个实用程序模块,可以帮助我们以标准方式处理任何特定操作的重试。在spring-retry中,所有配置都是基于简单注释的。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

使用步骤

POM依赖

<dependency>
<groupId>org.springframework.retrygroupId>
<artifactId>spring-retryartifactId>
dependency>

启用@Retryable

@EnableRetry
@SpringBootApplication
publicclassHelloApplication{

publicstaticvoidmain(String[]args){
SpringApplication.run(HelloApplication.class,args);
}

}

在方法上添加@Retryable

importcom.mail.elegant.service.TestRetryService;
importorg.springframework.retry.annotation.Backoff;
importorg.springframework.retry.annotation.Retryable;
importorg.springframework.stereotype.Service;
importjava.time.LocalTime;

@Service
publicclassTestRetryServiceImplimplementsTestRetryService{

@Override
@Retryable(value=Exception.class,maxAttempts=3,backoff=@Backoff(delay=2000,multiplier=1.5))
publicinttest(intcode)throwsException{
System.out.println("test被调用,时间:"+LocalTime.now());
if(code==0){
thrownewException("情况不对头!");
}
System.out.println("test被调用,情况对头了!");

return200;
}
}

来简单解释一下注解中几个参数的含义:

  • value:抛出指定异常才会重试
  • include:和value一样,默认为空,当exclude也为空时,默认所有异常
  • exclude:指定不处理的异常
  • maxAttempts:最大重试次数,默认3次
  • backoff:重试等待策略,默认使用@Backoff@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

当重试耗尽时还是失败,会出现什么情况呢?

当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallbackSpring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法。如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。

@Recover

@Recover
publicintrecover(Exceptione,intcode){
System.out.println("回调方法执行!!!!");
//记日志到数据库或者调用其余的方法
return400;
}

可以看到传参里面写的是 Exception e,这个是作为回调的接头暗号(重试次数用完了,还是失败,我们抛出这个Exception e通知触发这个回调方法)。对于@Recover注解的方法,需要特别注意的是:

  • 方法的返回值必须与@Retryable方法一致
  • 方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover方法中有的)
  • 该回调方法与重试方法写在同一个实现类里面

注意事项

  • 由于是基于AOP实现,所以不支持类里自调用方法
  • 如果重试失败需要给@Recover注解的方法做后续处理,那这个重试的方法不能有返回值,只能是void
  • 方法内不能使用try catch,只能往外抛异常
  • @Recover注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。

总结

本篇主要简单介绍了Springboot中的Retryable的使用,主要的适用场景和注意事项,当需要重试的时候还是很有用的。



审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 参数
    +关注

    关注

    11

    文章

    1769

    浏览量

    32061
  • spring
    +关注

    关注

    0

    文章

    338

    浏览量

    14302

原文标题:求求你们了,别再重复造轮子了,一个 Spring 注解轻松搞定循环重试功能!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Spring Boot如何实现异步任务

    ,用来告诉 Spring 这个方法是异步方法,Spring 会将这个方法的执行放在异步线程中进行。使用 @Async 注解需要满足以下条
    的头像 发表于 09-30 10:32 1394次阅读

    使用Spring自定义注解的实现

    执行器。其本质就是通过外部参数进行次路由和Spring mvc做的事情类似。简单看了Spring mvc的实现原理之后,决定使用自定义注解的方式来实现以上
    发表于 09-28 11:55 0次下载

    教你如何用注解搞定Spring Boot接口防刷

    ,技术要点: Spring Boot的基本知识,Redis基本操作,首先是写注解类: import java.lang.annotat
    的头像 发表于 09-13 09:23 1753次阅读

    关于Spring循环依赖问题

      Spring循环依赖,源码详细分析 → 真的非要三级缓存吗 中讲到了循环依赖问题
    的头像 发表于 06-14 17:21 1728次阅读

    浅谈Spring事务底层原理

    开启Spring事务本质上就是增加了Advisor,但我们使用@EnableTransactionManagement注解来开启Spring
    的头像 发表于 12-06 09:56 671次阅读

    从源码层面深度剖析Spring循环依赖

    参考图中 spring 解决循环依赖 的过程可知,spring 利用三级缓中的 objectFactory 生成并返回 early 对象
    的头像 发表于 12-22 10:34 513次阅读

    Spring Web MVC注解

    RequestMapping注解的主要用途是将Web请求与请求处理类中的方法进行映射。Spring MVC和Spring WebFlux都通过`RquestMappingHandlerMapping`和`RequestMappi
    的头像 发表于 04-07 11:32 575次阅读
    <b class='flag-5'>Spring</b> Web MVC<b class='flag-5'>注解</b>

    Spring Bean相关的4注解及使用方法

    ComponentScan`注解用于配置Spring需要扫描的被组件注解注释的类所在的包。可以通过配置其basePackages属性或者value属性来配置需要扫描的包路径。value属性是basePackages的别名。此
    的头像 发表于 04-07 11:33 1312次阅读
    <b class='flag-5'>Spring</b> Bean相关的4<b class='flag-5'>个</b><b class='flag-5'>注解</b>及使用方法

    Spring Dependency Inject与Bean Scops注解

    DependsOn`注解可以配置Spring IoC容器在初始化Bean之前,先初始化其他的Bean对象。下面是此注解使用示例代码:
    的头像 发表于 04-07 11:35 652次阅读
    <b class='flag-5'>Spring</b> Dependency Inject与Bean Scops<b class='flag-5'>注解</b>

    容器配置及Spring Boot注解

    Autowired注解用于标记Spring将要解析和注入的依赖项。此注解可以作用在构造函数、字段和setter方法上。
    的头像 发表于 04-07 11:45 551次阅读
    容器配置及<b class='flag-5'>Spring</b> Boot<b class='flag-5'>注解</b>

    Spring中@Component注解是怎么实现的

    想必`@Component`注解大家直在使用,只要类上加上它,就可以被Spring容器管理,那大家有想过它是怎么实现的吗?本篇文章就带领到家揭秘。
    的头像 发表于 04-07 15:23 1526次阅读
    <b class='flag-5'>Spring</b>中@Component<b class='flag-5'>注解</b>是怎么实现的

    Spring Kafka的各种用法

    Kafka 是不支持消息重试的。但是 Spring Kafka 2.7+ 封装了 Retry Topic 这个功能。 1. @RetryableTopic 使用注解的方式启用 Ret
    的头像 发表于 09-25 17:04 923次阅读

    spring事务失效的些场景

    致的情况,我们般都会用到spring事务。 确实,spring事务用起来贼爽,就用简单
    的头像 发表于 10-08 14:27 422次阅读
    <b class='flag-5'>spring</b>事务失效的<b class='flag-5'>一</b>些场景

    springboot核心注解

    Spring Boot 是基于 Spring 框架的开源框架,它可以帮助开发者快速构建、部署和运行独立的、生产级的 Spring 应用程序。Spring Boot 提供了
    的头像 发表于 11-23 09:23 489次阅读

    SpringBoot核心注解由几个注解组成

    Spring Boot 是开源的 JavaEE 开发框架,它以简化 Spring 框架的配置与开发为目标,旨在让开发者能快速构建独立、生产级别的应用程序。
    的头像 发表于 12-03 15:09 700次阅读