@Retryable 注释不适用于非 Spring Bean 类方法

Joy*_*Joy 1 java spring spring-retry spring-boot

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

  1. 添加spring-retry到 pom.xml。

  2. 添加了以下配置:

    @Configuration
    @EnableRetry
    public class RetryConfiguration {
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 最后@Retryable向类(此类不是 Spring Bean)方法添加注释,我希望针对各种异常重试该方法,如下所示:

    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);
      }
    
    Run Code Online (Sandbox Code Playgroud)

现在,该executeRequest方法不再重试。我无法理解我是否在这里遗漏了任何东西。

有人可以帮忙吗?谢谢。

hov*_*yan 5

如果您的类不是 Spring 管理的(例如@Component/@Bean),则注释处理器将@Retryable不会拾取它。

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

RetryTemplate.builder()
        .maxAttempts(2)
        .exponentialBackoff(100, 10, 1000)
        .retryOn(RestClientException.class)
        .traversingCauses()
        .build();
Run Code Online (Sandbox Code Playgroud)

进而

retryTemplate.execute(context -> myService.execute(request));
Run Code Online (Sandbox Code Playgroud)

如果您想重试多个异常,可以通过自定义来实现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();
Run Code Online (Sandbox Code Playgroud)

仅供参考:RetryTemplate正在阻塞,您可能想探索非阻塞异步重试方法,例如async-retry。- 并且retryOn()支持例外列表。