【问题标题】:@Retryable annotation not working for non Spring Bean class method@Retryable 注解不适用于非 Spring Bean 类方法
【发布时间】:2021-11-23 10:41:29
【问题描述】:

我是spring-retry 的新手。基本上,为了重试对 REST API 的调用,我已将 spring-retry 集成到我的 spring-boot 应用程序中。为此,我进行了以下更改:

  1. 在 pom.xml 中添加了spring-retry

  2. 添加如下配置:

    @Configuration
    @EnableRetry
    public class RetryConfiguration {
    }
    
  3. 最后在类(这个类不是Spring Bean)方法上加了@Retryable注解,各种异常我想重试如下:

    public class OAuth1RestClient extends OAuthRestClient {
    
      @Override
      @Retryable(maxAttempts = 3, value = {
         Exception.class},
         backoff = @Backoff(delay = 100, multiplier = 3))
      public Response executeRequest(OAuthRequest request)
          throws InterruptedException, ExecutionException, IOException {
         System.out.println("Inside Oauth1 client");
         return myService.execute(request);
      }
    

现在,executeRequest 方法不会重试。如果我在这里遗漏了什么,我无法理解。

有人可以帮忙吗?谢谢。

【问题讨论】:

  • 如果不是spring bean,这行不通。仅 AOP(默认情况下)适用于 Spring 托管 bean。
  • @M.Deinum 谢谢。因此,在这种情况下,我想剩下的唯一选择是使用 RetryTemplate,以便使上述方法重试。

标签: java spring spring-boot spring-retry


【解决方案1】:

如果你的类不是 Spring 管理的(例如 @Component/@Bean) @Retryable 的注释处理器不会接收它。

您始终可以手动定义 retryTemplate 并用它包装调用:

RetryTemplate.builder()
        .maxAttempts(2)
        .exponentialBackoff(100, 10, 1000)
        .retryOn(RestClientException.class)
        .traversingCauses()
        .build();

然后

retryTemplate.execute(context -> myService.execute(request));

如果您想重试多个异常,这可以通过自定义RetryPolicy 实现

Map<Class(? extends Throwable), Boolean> exceptionsMap = new HashMap<>();
exceptionsMap.put(InternalServerError.class, true);
exceptionsMap.put(RestClientException.class, true);

SimpleRetryPolicy policy = new SimpleRetryPolicy(5, exceptionsMap, true); 
RetryTemplate.builder()
        .customPolicy(policy)
        .exponentialBackoff(100, 10, 1000)
        .build();

仅供参考:RetryTemplate 处于阻塞状态,您可能想探索像 async-retry 这样的非阻塞异步重试方法。 - 并且retryOn() 支持异常列表。

【讨论】:

  • 谢谢。使用 RetryTemplate 我可以重试多个异常,例如: RestClientException.class 和 InternalServerError.class ?
  • 是的 - 查看更新的答案
  • 谢谢。但是使用重试模板,我仍然无法在异常上重试所需的方法。让我发布一个详细说明该问题的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
  • 2012-11-11
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多