Springboot Retry组件@Recover失效问题怎么解决
发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章主要介绍"Springboot Retry组件@Recover失效问题怎么解决",在日常操作中,相信很多人在Springboot Retry组件@Recover失效问题怎么解决问题上存在疑惑,
千家信息网最后更新 2026年10月31日Springboot Retry组件@Recover失效问题怎么解决
这篇文章主要介绍"Springboot Retry组件@Recover失效问题怎么解决",在日常操作中,相信很多人在Springboot Retry组件@Recover失效问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Springboot Retry组件@Recover失效问题怎么解决"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
背景
在使用springboot的retry模块时,你是否出现过@Recover注解失效的问题呢?下面我会对该问题进行复现,并且简要的说下解决方法。
问题复现
首先我们引入maven
org.springframework.retry spring-retry org.aspectj aspectjweaver 1.9.6 cn.hutool hutool-all 5.5.2 org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-web
主类配置EnableRetry注解
package ai.guiji.csdn; import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.retry.annotation.EnableRetry; @EnableRetry@SpringBootApplicationpublic class CsdnApplication { public static void main(String[] args) { SpringApplication.run(CsdnApplication.class, args); }}准备测试的Retry组件类代码
package ai.guiji.csdn.component; import lombok.extern.slf4j.Slf4j;import org.springframework.retry.annotation.Backoff;import org.springframework.retry.annotation.Recover;import org.springframework.retry.annotation.Retryable;import org.springframework.stereotype.Component; import java.util.function.Supplier; /** @Author 剑客阿良_ALiang @Date 2021/4/22 16:07 @Description: 重试工具 */@Slf4j@Componentpublic class RetryUtil { @Retryable( value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 5000, multiplier = 1.5)) public String retry(Supplier supplier) throws Exception { String result = null; try { result = supplier.get(); } catch (Exception exception) { log.error("异常报错:{}", exception.getMessage()); throw exception; } return result; } @Recover public void recover(Exception e) { log.error("调用超过3次异常"); }} 代码说明
1、我们可以看到retry方法会重试supplier的get结果,捕获异常并抛出异常。这里抛出后会被retry捕获并且重试。
2、maxAttempts参数为重试的最大次数。
3、backoff中的delay为两次重试之间的延迟,multiplier为重试阻尼,可以这么理解,每次重试间隔时间为上一次重试间隔时间的倍数。
4、如果3次重试均抛出异常,则进入recover方法。
编写测试代码
package ai.guiji.csdn.component; import cn.hutool.core.convert.Convert;import cn.hutool.http.HttpUtil;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest; /** @Author 剑客阿良_ALaing @Date 2021/11/30 13:08 @Description: */@SpringBootTestclass RetryUtilTest { @Autowired private RetryUtil retryUtil; @Test void retry() { try { System.out.println(Convert.toStr(retryUtil.retry(() -> HttpUtil.post("xxxx", "")), "haha")); } catch (Exception exception) { exception.printStackTrace(); } }}执行测试结果
2021-11-30 13:37:44.012 ERROR 13600 --- [ main] ai.guiji.csdn.component.RetryUtil : 异常报错:UnknownHostException: xxxx2021-11-30 13:37:49.019 ERROR 13600 --- [ main] ai.guiji.csdn.component.RetryUtil : 异常报错:UnknownHostException: xxxx2021-11-30 13:37:58.787 ERROR 13600 --- [ main] ai.guiji.csdn.component.RetryUtil : 异常报错:UnknownHostException: xxxxorg.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is cn.hutool.core.io.IORuntimeException: UnknownHostException: xxxx at org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler.recover(RecoverAnnotationRecoveryHandler.java:70) at org.springframework.retry.interceptor.RetryOperationsInterceptor$ItemRecovererCallback.recover(RetryOperationsInterceptor.java:142) at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:539) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:387) at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:225) at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:116) at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:163) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) at ai.guiji.csdn.component.RetryUtil$$EnhancerBySpringCGLIB$$d209cbc6.retry() at ai.guiji.csdn.component.RetryUtilTest.retry(RetryUtilTest.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at java.util.ArrayList.forEach(ArrayList.java:1257) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at java.util.ArrayList.forEach(ArrayList.java:1257) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)Caused by: cn.hutool.core.io.IORuntimeException: UnknownHostException: xxxx at cn.hutool.http.HttpRequest.send(HttpRequest.java:1153) at cn.hutool.http.HttpRequest.execute(HttpRequest.java:969) at cn.hutool.http.HttpRequest.execute(HttpRequest.java:940) at cn.hutool.http.HttpUtil.post(HttpUtil.java:216) at cn.hutool.http.HttpUtil.post(HttpUtil.java:197) at ai.guiji.csdn.component.RetryUtilTest.lambda$retry$0(RetryUtilTest.java:17) at ai.guiji.csdn.component.RetryUtil.retry(RetryUtil.java:22) at ai.guiji.csdn.component.RetryUtil$$FastClassBySpringCGLIB$$a565f63f.invoke( ) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) at org.springframework.retry.interceptor.RetryOperationsInterceptor$1.doWithRetry(RetryOperationsInterceptor.java:93) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) ... 73 moreCaused by: java.net.UnknownHostException: xxxx at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at java.net.Socket.connect(Socket.java:538) at sun.net.NetworkClient.doConnect(NetworkClient.java:180) at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) at sun.net.www.http.HttpClient. (HttpClient.java:242) at sun.net.www.http.HttpClient.New(HttpClient.java:339) at sun.net.www.http.HttpClient.New(HttpClient.java:357) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1220) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1156) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1050) at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:984) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309) at cn.hutool.http.HttpConnection.getOutputStream(HttpConnection.java:451) at cn.hutool.http.HttpRequest.sendFormUrlEncoded(HttpRequest.java:1176) at cn.hutool.http.HttpRequest.send(HttpRequest.java:1145) ... 86 more Process finished with exit code 0
并没有进入recover方法,注解未触发。
问题解决
这里有个很容易忽视的点,就是retry方法是有返回值的,所以recover方法也必须是相同类型带返回值的方法。所以要把recover方法改一下。
package ai.guiji.csdn.component; import lombok.extern.slf4j.Slf4j;import org.springframework.retry.annotation.Backoff;import org.springframework.retry.annotation.Recover;import org.springframework.retry.annotation.Retryable;import org.springframework.stereotype.Component; import java.util.function.Supplier; /** @Author 剑客阿良_ALiang @Date 2021/4/22 16:07 @Description: 重试工具 */@Slf4j@Componentpublic class RetryUtil { @Retryable( value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 5000, multiplier = 1.5)) public String retry(Supplier supplier) throws Exception { String result = null; try { result = supplier.get(); } catch (Exception exception) { log.error("异常报错:{}", exception.getMessage()); throw exception; } return result; } @Recover public String recover(Exception e) { log.error("调用超过3次异常"); return "调用超过3次异常"; }} 重新执行测试看下结果
到此,关于"Springboot Retry组件@Recover失效问题怎么解决"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
问题
方法
组件
学习
测试
代码
剑客
注解
结果
阿良
工具
时间
更多
帮助
实用
最大
相同
接下来
之间
倍数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技股
广东万易互联网科技有限公司惠州分公司
上海卓越科技互联网
重生之互联网科技帝国
科技与互联网发展
九亚互联网科技
米客互联网科技
互联网科技生活的内容
互联网公司会议桌创意科技软装饰
湖南洣水互联网科技有限公司扣款
博兴的互联网电子科技公司
云创客互联网科技公司
湖北码尼互联网科技有限公司电话
苏州五指互联网络科技有限
洛阳共同富裕互联网科技有限公司
朱啸虎曾投资哪些互联网科技企业
互联网科技股为什么大涨
风投北京互联网科技
互联网金融金融科技
科技美学互联网 艺术
耶加雪菲
百单网互联网科技有限公司
科技和互联网公司
深圳互联网络科技有限公司
小马过河互联网科技
成都狮子座互联网科技
互联网科技公司实习生
哈尔滨屹滨互联网科技有限公司
宇信科技在杭州互联网排第几
艺电能源互联网科技有限公司招聘