06-Spring Retry
2026/9/27大约 6 分钟
一、快速开始
第一步:导入jar
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>第二步:在启动类上通过@EnableRetry开启
@SpringBootApplication
@EnableRetry
public class TestSpringApplication {
public static void main(String[] args) {
SpringApplication.run(TestSpringApplication.class, args);
}
}第三步:使用@Retryable定义接口:
public interface SpringRetryService {
String retryMethod() throws Exception;
}
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class)
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}第四步:测试
@SpringBootTest
public class TestApplication {
@Resource
private SpringRetryService springRetryService;
@Test
public void test() throws Exception {
springRetryService.retryMethod();
}
}输出结果:
Tue Jul 08 13:33:48 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:33:49 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:33:50 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:33:51 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zero二、@Retryable注解
@Retryable注解:
| 属性 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| recover | String | "" | 标记了 @Recover 的方法名称,进行降级处理或错误补偿 |
| value | Class<? extends Throwable>[] | {} | 重试的异常类 |
| include | Class<? extends Throwable>[] | {} | 重试的异常类 |
| exclude | Class<? extends Throwable>[] | {} | 不重试的异常类 |
| maxAttempts | int | 3 | 重试的次数 |
| maxAttemptsExpression | String | "" | 重试的次数SPEL表达式 |
| stateful | boolean | false | 是否采用有状态重试,即在同一个参数下异常时,能够记住此前的重试状态 |
| backoff | Backoff | @Backoff | 含义 |
| exceptionExpression | String | "" | 含义 |
| listeners | String[] | {} | 含义 |
| interceptor | String | "" | 含义 |
2.1 recover属性
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class)
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
@Recover
public String retryMethod(Exception ex){
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message="+ex.getMessage());
return "FAIL";
}
}结果:
Tue Jul 08 13:36:57 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:36:58 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:36:59 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:37:00 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:37:00 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=/ by zero
FAIL2.2 value、include、exclude属性
方式1设置value和exclude属性:
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,exclude = {ArithmeticException.class})
public String retryMethod()throws Exception {
System.out.println("class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}结果:未重试
Tue Jul 08 13:39:03 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zero方式2设置include和exclude属性:
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(include = {ArithmeticException.class},exclude = {ArithmeticException.class})
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}结果:未重试
Tue Jul 08 13:39:03 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zeroexclude的效果高于include。
2.3 maxAttempts、maxAttemptsExpression属性
只设置maxAttempts
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,maxAttempts = 5)
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}结果:由默认的3次改为5次
Tue Jul 08 13:41:15 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:41:16 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:41:17 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:41:18 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:41:19 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zero只设置maxAttemptsExpression
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,maxAttemptsExpression = "#{3+3}")
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}结果重试6次
Tue Jul 08 13:43:43 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:43:44 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:43:45 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:43:46 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:43:47 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:43:48 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zero同时设置maxAttempts、maxAttemptsExpression属性,maxAttemptsExpression大于maxAttempts
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,maxAttempts = 4,maxAttemptsExpression = "#{3+3}")
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}结果:
Tue Jul 08 13:45:20 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:45:21 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:45:22 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:45:23 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:45:24 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:45:25 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zero同时设置maxAttempts、maxAttemptsExpression属性,maxAttemptsExpression 小于 maxAttempts
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,maxAttempts = 7,maxAttemptsExpression = "#{3+3}")
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod");
int x = 10/0;
return "OK";
}
}结果:
Tue Jul 08 13:47:28 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:47:29 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:47:30 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:47:31 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:47:32 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
Tue Jul 08 13:47:33 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message= execute retryMethod
java.lang.ArithmeticException: / by zeromaxAttemptsExpression的优先级高于maxAttempts。
2.4 stateful 属性
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,stateful=true)
public String retryMethod(Integer param)throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message="+param);
int i = 10 / param;
return "param="+i;
}
}
@SpringBootTest
public class TestApplication {
@Resource
private SpringRetryService springRetryService;
@Test
public void test() throws Exception {
for (int i = 0; i < 6; i++) {
try {
int param = i % 2;
System.out.println(springRetryService.retryMethod(param));
} catch (Exception e) {
System.out.println("class=TestApplication,method=test,message=" + e.getMessage());
}
}
}
}结果:不重试
Tue Jul 08 14:02:52 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=0
class=TestApplication,method=test,message=/ by zero
Tue Jul 08 14:02:53 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=1
param=10
Tue Jul 08 14:02:53 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=0
class=TestApplication,method=test,message=/ by zero
Tue Jul 08 14:02:54 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=1
param=10
Tue Jul 08 14:02:54 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=0
class=TestApplication,method=test,message=/ by zero
Tue Jul 08 14:02:54 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=1
param=102.5 backoff属性
backoff注解:
public @interface Backoff {
long value() default 1000L;
// 等待发起重试的时间,单位毫秒
long delay() default 0L;
// 等待发起重试的时间,最大的阻塞时间
long maxDelay() default 0L;
// 每次重试延迟时间的增长倍数
double multiplier() default 0.0;
String delayExpression() default "";
String maxDelayExpression() default "";
String multiplierExpression() default "";
// 为每次重试延迟加上一定的随机扰动
boolean random() default false;
}测试1:
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,backoff=@Backoff(delay = 3000L))
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod");
int i = 10 / 0;
return "OK";
}
}
@SpringBootTest
public class TestApplication {
@Resource
private SpringRetryService springRetryService;
@Test
public void test() throws Exception {
System.out.println(springRetryService.retryMethod());
}
}结果:时间间隔3秒
Tue Jul 08 14:14:31 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:14:34 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:14:37 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
java.lang.ArithmeticException: / by zero测试2:
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,maxAttempts = 5,backoff=@Backoff(delay = 3000L, multiplier = 2))
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod");
int i = 10 / 0;
return "OK";
}
}
@SpringBootTest
public class TestApplication {
@Resource
private SpringRetryService springRetryService;
@Test
public void test() throws Exception {
System.out.println(springRetryService.retryMethod());
}
}结果:发起等待时间3秒、6秒、12秒、24秒。
Tue Jul 08 14:26:06 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:26:09 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:26:15 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:26:27 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:26:51 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
java.lang.ArithmeticException: / by zero测试3:
@Service
public class SpringRetryServiceImpl implements SpringRetryService {
@Override
@Retryable(value = Exception.class,maxAttempts = 5,backoff=@Backoff(delay = 3000L, multiplier = 2,maxDelay = 8000L))
public String retryMethod()throws Exception {
System.out.println(new Date()+"class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod");
int i = 10 / 0;
return "OK";
}
}
@SpringBootTest
public class TestApplication {
@Resource
private SpringRetryService springRetryService;
@Test
public void test() throws Exception {
System.out.println(springRetryService.retryMethod());
}
}结果:发起等待时间3秒、6秒、8秒、8秒。
Tue Jul 08 14:24:09 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:24:12 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:24:18 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:24:26 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
Tue Jul 08 14:24:34 CST 2025class=SpringRetryServiceImpl,method=retryMethod,message=execute retryMethod
java.lang.ArithmeticException: / by zero