You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@Retryable注解value属性未按预期生效 配置指定异常仍触发所有异常重试

@Retryable注解异常过滤失效问题原因及解决方案

问题原因

  • Spring Retry版本缺陷:1.2.5之前的Spring Retry版本存在已知BUG,当被@Retryable标注的方法同时配有@Recover恢复方法时,注解value属性的异常过滤逻辑会失效,所有RuntimeException都会触发重试。
  • 全局配置覆盖:如果容器中存在自定义的全局RetryTemplate Bean,且该Bean的重试策略配置为对所有异常重试,@Retryable注解默认会复用该全局配置,覆盖注解上的value属性配置。
  • 异常包装场景:如果业务代码中存在其他AOP切面或者异常捕获逻辑,将原本的非指定异常包装为IllegalArgumentException抛出,也会触发重试,可通过打印完整异常栈排查该情况。

解决方案

  1. 优先升级Spring Retry版本到1.2.5及以上,该版本官方已经修复了@Recover导致的异常过滤失效BUG。
  2. 版本无法升级时,显式在@Retryable注解中添加exclude属性,明确排除不需要重试的异常,配置示例:
@Retryable(value = {IllegalArgumentException.class}, exclude = {HttpClientErrorException.class, Exception.class}, maxAttempts = 2, backoff = @Backoff(delay = 50))
  1. 存在全局RetryTemplate配置的场景,可在@Retryable注解中通过exceptionExpression属性显式指定异常匹配规则,强制只对指定异常重试,配置示例:
@Retryable(value = {IllegalArgumentException.class}, exceptionExpression = "T(java.lang.IllegalArgumentException).isInstance(#root)", maxAttempts = 2, backoff = @Backoff(delay = 50))
  1. 针对查找@Recover方法耗时的问题,可添加兜底恢复方法,避免异常匹配时的遍历消耗:
@Recover
public ResponseEntity<Object> recoverAll(Exception e, UUID subscriptionId){
    // 可根据需求选择直接抛出原异常或者返回通用降级结果
    throw e;
}

内容的提问来源于stack exchange,提问作者Ignacio Escursell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 23:36:03