【问题标题】:Spring Boot @Retryable maxAttempts according to exceptionSpring Boot @Retryable maxAttempts 根据异常
【发布时间】:2020-09-23 13:54:08
【问题描述】:

我想知道关于 Spring Boot @Retryable 注释的一些事情。

我想根据异常类型实现@RetryablemaxAttemps count,比如:

if Exception type is ExceptionA:
@Retryable(value = ExceptionA.class, maxAttempts = 2)
if Exception type is ExceptionB:
@Retryable(value = ExceptionB.class, maxAttempts = 5)

是否可以使用@Retryable注解,或者有什么建议?

【问题讨论】:

    标签: java spring spring-boot spring-retry


    【解决方案1】:

    不是直接的;您必须构建一个自定义拦截器 (RetryInterceptorBuilder) bean 并在 @Retryable.interceptor 中提供其 bean 名称。

    使用ExceptionClassifierRetryPolicy 为每个异常使用不同的策略。

    编辑

    这是一个例子:

    @SpringBootApplication
    @EnableRetry
    public class So64029544Application {
    
        public static void main(String[] args) {
            SpringApplication.run(So64029544Application.class, args);
        }
    
    
        @Bean
        public ApplicationRunner runner(Retryer retryer) {
            return args -> {
                retryer.toRetry("state");
                retryer.toRetry("arg");
            };
        }
    
        @Bean
        public Object retryInterceptor(Retryer retryer) throws Exception {
            ExceptionClassifierRetryPolicy policy = new ExceptionClassifierRetryPolicy();
            policy.setPolicyMap(Map.of(
                    IllegalStateException.class, new SimpleRetryPolicy(2),
                    IllegalArgumentException.class, new SimpleRetryPolicy(3)));
            Method recover = retryer.getClass().getDeclaredMethod("recover", Exception.class);
            return RetryInterceptorBuilder.stateless()
                    .retryPolicy(policy)
                    .backOffOptions(1_000, 1.5, 10_000)
                    .recoverer(new RecoverAnnotationRecoveryHandler<>(retryer, recover))
                    .build();
        }
    }
    
    @Component
    class Retryer {
    
        @Retryable(interceptor = "retryInterceptor")
        public void toRetry(String in) {
            System.out.println(in);
            if ("state".equals(in)) {
                throw new IllegalStateException();
            }
            else {
                throw new IllegalArgumentException();
            }
        }
    
        @Recover
        public void recover(Exception ex) {
            System.out.println("Recovered from " + ex
                    + ", retry count:" + RetrySynchronizationManager.getContext().getRetryCount());
        }
    
    }
    
    state
    state
    Recovered from java.lang.IllegalStateException, retry count:2
    arg
    arg
    arg
    Recovered from java.lang.IllegalArgumentException, retry count:3
    

    【讨论】:

    • 您能分享实现上述方法的示例或文档吗?
    • @Deadpool 我在答案中添加了一个示例。
    猜你喜欢
    • 1970-01-01
    • 2019-11-03
    • 2020-11-25
    • 2018-08-08
    • 2018-06-30
    • 2019-01-06
    • 2019-12-26
    • 2019-09-05
    • 1970-01-01
    相关资源
    最近更新 更多