扒一扒@Retryable注解,很优雅,有点意思

2024-02-23 07:20

本文主要是介绍扒一扒@Retryable注解,很优雅,有点意思,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

你好呀,我是动作缓慢的程序猿

可关注公众号 :动作缓慢的程序猿    领取最新大厂面试题

前几天我 Review 代码的时候发现项目里面有一坨逻辑写的非常的不好,一眼望去简直就是丑陋之极。

我都不知道为什么会有这样的代码存在项目里面,于是我看了一眼提交记录准备叫对应的同事问问,为什么会写出这样的代码。

然后...

那一坨代码是我 2019 年的时候提交的。

我细细的思考了一下,当时好像由于对项目不熟悉,然后其他的项目里面又有一个类似的功能,我就直接 CV 大法搞过来了,里面的逻辑也没细看。

嗯,原来是历史原因,可以理解,可以理解。

代码里面主要就是一大坨重试的逻辑,各种硬编码,各种辣眼睛的补丁。

特别是针对重试的逻辑,到处都有。所以我决定用一个重试组件优化一波。

今天就带大家卷一下 Spring-retry 这个组件。

 

丑陋的代码

先简单的说一下丑陋的代码大概长什么样子吧。

给你一个场景,假设你负责支付服务,需要对接外部的一个渠道,调用他们的订单查询接口。

他们给你说:由于网络问题,如果我们之间交互超时了,你没有收到我的任何响应,那么按照约定你可以对这个接口发起三次重试,三次之后还是没有响应,那就应该是有问题了,你们按照异常流程处理就行。

假设你不知道 Spring-retry 这个组件,那么你大概率会写出这样的代码:

逻辑很简单嘛,就是搞个 for 循环,然后异常了就发起重试,并对重试次数进行检查。

然后搞个接口来调用一下:

 发起调用之后,日志的输出是这样的,一目了然,非常清晰:

 

正常调用一次,重试三次,一共可以调用 4 次。在第五次调用的时候抛出异常。

完全符合需求,自测也完成了,可以直接提交代码,交给测试同学了。

非常完美,但是你有没有想过,这样的代码其实非常的不优雅。

你想,如果再来几个类似的“超时之后可以发起几次重试”需求。

那你这个 for 循环是不是得到处的搬来搬去。就像是这样似的,丑陋不堪:

 实话实说,我以前也写过这样的丑代码。

 

但是我现在是一个有代码洁癖的人,这样的代码肯定是不能忍的。

重试应该是一个工具类一样的通用方法,是可以抽离出来的,剥离到业务代码之外,开发的时候我们只需要关注业务代码写的巴巴适适就行了。

那么怎么抽离呢?

你说巧不巧,我今天给你分享这个的东西,就把重试功能抽离的非常的好:

 用上 spring-retry 之后,我们上面的代码就变成了这样:

只是加上了一个 @Retryable 注解,这玩意简直简单到令人发指。

一眼望去,非常的优雅!

所以,我决定带大家扒一扒这个注解。看看别人是怎么把“重试”这个功能抽离成一个组件的,这比写业务代码有意思。

我这篇文章不会教大家怎么去使用 spring-retry,它的功能非常的丰富,写用法的文章已经非常多了。我想写的是,当我会使用它之后,我是怎么通过源码的方式去了解它的。

怎么把它从一个只会用的东西,变成简历上的那一句:翻阅过相关源码。

 

可添加公众号领取免费大厂面试资料:动作缓慢的程序猿

但是你要压根都不会用,都没听过这个组件怎么办呢?

没关系,我了解一个技术点的第一步,一定是先搭建出一个非常简单的 Demo。

没有跑过 Demo 的一律当做一无所知处理。

先搭 Demo

我最开始也是对这个注解一无所知的。

所以,对于这种情况,废话少说,先搞个 Demo 跑起来才是王道。

但是你记住搭建 Demo 也是有技巧的:直接去官网或者 github 上找就行了,那里面有最权威的、最简洁的 Demo。

比如 spring-retry 的 github 上的 Quick Start 就非常简洁易懂。

它分别提供了注解式开发和编程式开发的示例。

我们这里主要看它的注解式开发案例:

里面涉及到三个注解:

  • @EnableRetry:加在启动类上,表示支持重试功能。

  • @Retryable:加在方法上,就会给这个方法赋能,让它有用重试的功能。

  • @Recover:重试完成后还是不成功的情况下,会执行被这个注解修饰的方法。

看完 git 上的 Quick Start 之后,我很快就搭了一个 Demo 出来。

如果你之前不了解这个组件的使用方法的话,我强烈建议你也搭一个,非常的简单。

首先是引入 maven 依赖:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.3.1</version>
</dependency>

由于该组件是依赖于 AOP 给你的,所以还需要引入这个依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.6.1</version>
</dependency>

然后是代码,就这么一点,就够够的了:

 

 最后把项目跑起来,调用一笔,确实是生效了,执行了 @Recover 修饰的方法:

<

这篇关于扒一扒@Retryable注解,很优雅,有点意思的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/737900

相关文章

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

Java中基于注解的代码生成工具MapStruct映射使用详解

《Java中基于注解的代码生成工具MapStruct映射使用详解》MapStruct作为一个基于注解的代码生成工具,为我们提供了一种更加优雅、高效的解决方案,本文主要为大家介绍了它的具体使用,感兴趣... 目录介绍优缺点优点缺点核心注解及详细使用语法说明@Mapper@Mapping@Mappings@Co

Java中注解与元数据示例详解

《Java中注解与元数据示例详解》Java注解和元数据是编程中重要的概念,用于描述程序元素的属性和用途,:本文主要介绍Java中注解与元数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参... 目录一、引言二、元数据的概念2.1 定义2.2 作用三、Java 注解的基础3.1 注解的定义3.2 内

SpringBoot使用注解集成Redis缓存的示例代码

《SpringBoot使用注解集成Redis缓存的示例代码》:本文主要介绍在SpringBoot中使用注解集成Redis缓存的步骤,包括添加依赖、创建相关配置类、需要缓存数据的类(Tes... 目录一、创建 Caching 配置类二、创建需要缓存数据的类三、测试方法Spring Boot 熟悉后,集成一个外

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

轻松掌握python的dataclass让你的代码更简洁优雅

《轻松掌握python的dataclass让你的代码更简洁优雅》本文总结了几个我在使用Python的dataclass时常用的技巧,dataclass装饰器可以帮助我们简化数据类的定义过程,包括设置默... 目录1. 传统的类定义方式2. dataclass装饰器定义类2.1. 默认值2.2. 隐藏敏感信息

Go信号处理如何优雅地关闭你的应用

《Go信号处理如何优雅地关闭你的应用》Go中的优雅关闭机制使得在应用程序接收到终止信号时,能够进行平滑的资源清理,通过使用context来管理goroutine的生命周期,结合signal... 目录1. 什么是信号处理?2. 如何优雅地关闭 Go 应用?3. 代码实现3.1 基本的信号捕获和优雅关闭3.2

C#如何优雅地取消进程的执行之Cancellation详解

《C#如何优雅地取消进程的执行之Cancellation详解》本文介绍了.NET框架中的取消协作模型,包括CancellationToken的使用、取消请求的发送和接收、以及如何处理取消事件... 目录概述与取消线程相关的类型代码举例操作取消vs对象取消监听并响应取消请求轮询监听通过回调注册进行监听使用Wa

使用@Slf4j注解,log.info()无法使用问题

《使用@Slf4j注解,log.info()无法使用问题》在使用Lombok的@Slf4j注解打印日志时遇到问题,通过降低Lombok版本(从1.18.x降至1.16.10)解决了问题... 目录@Slf4androidj注解,log.info()无法使用问题最后解决总结@Slf4j注解,log.info(

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免