2025年2月7日 spring-retry
参考
- github库地址
- 如果需要更深入学习,这里有官方文档
- Spring Retry 教程
- 我的示例就是基于这篇文章
引言
一直想学习下 spring-retry,不过之前的工作中一直没有用到,也就一直拖下来了直到现在。
虽然之前有看到一些相关文章,但是这个项目本身的引用量好像也不是很大。
spring-retry 更像一个小工具,没有 spring framework 那样的官方文档网页,如果需要深入学习,可以直接看 github 库上的文档
下面写了一个小demo,感觉确实在 spring 项目中,如果需要重试的场景,使用起来代码确实很简洁优雅。
用法上类似于 Spring 事务,同样有编程式和注解式两种用法,同样的更倾向于注解式使用方法
示例
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>study.hwj</groupId>
<artifactId>study-spring-retry</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.11</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.11</version>
</dependency>
</dependencies>
</project>
spring配置类
package study.hwj;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
@ComponentScan
@Configuration
@EnableRetry
public class AppConfig {
@Bean
public RetryTemplate retryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000L);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(2);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.registerListener(new MyRetryListener());
return retryTemplate;
}
}
监听器
package study.hwj;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.stereotype.Component;
@Component
public class MyRetryListener implements RetryListener {
@Override
public <T, E extends Throwable> boolean open(RetryContext context,
RetryCallback<T, E> callback) {
System.out.println("onOpen");
// return super.open(context, callback);
return true;
}
@Override
public <T, E extends Throwable> void close(RetryContext context,
RetryCallback<T, E> callback, Throwable throwable) {
System.out.println("onClose");
// super.close(context, callback, throwable);
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
System.out.println("onError");
// super.onError(context, callback, throwable);
}
@Override
public <T, E extends Throwable> void onSuccess(RetryContext context, RetryCallback<T, E> callback, T result) {
System.out.println("onSuccess");
}
}
业务类,直接使用 RetryTemplate
package study.hwj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;
@Component
public class RetryService {
@Autowired
public RetryTemplate retryTemplate;
static int count = 0;
public void doRetry() {
retryTemplate.execute(context -> {
System.out.println("start 1...");
if (count < 2) {
System.out.println("count is " + count);
count++;
throw new RuntimeException("1");
}
System.out.println("end 1...");
return "xx";
});
}
}
业务类,使用注解
package study.hwj;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
@Component
public class RetryServiceWithAnnotation {
static int count = 0;
@Retryable(retryFor = RuntimeException.class, maxAttempts = 5)
public void doRetry() {
System.out.println("start 1...");
if (count < 4) {
System.out.println("count is " + count);
count++;
throw new RuntimeException("1");
}
System.out.println("end 1...");
}
}
测试类
package study.hwj;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
// 两种使用方式,类似于Spring事务的使用
// 1. 编程式:直接用RetryTemplate
// RetryService retryService = applicationContext.getBean(RetryService.class);
// retryService.doRetry();
// 2. 注解式: @EnableRetry + @Retryable ,不需要定义 RetryTemplate
RetryServiceWithAnnotation retryService = applicationContext.getBean(RetryServiceWithAnnotation.class);
retryService.doRetry();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2017-02-07 使用JDBC进行批处理