首页 > 解决方案 > 每次 Spring Retry 尝试更改参数值

问题描述

我有以下方法是@Retryable:

    @Retryable(value = HttpClientErrorException.class)
    public Integer callToExternalService(DateTime start, DateTime end) throws MyException

我的问题是我是否可以在每次重试方法时修改输入参数,因为我需要使用不同的值进行休息调用。有没有类似于@Recover这种情况的选项?

标签: springspring-retry

解决方案


不是开箱即用;您需要添加比重试拦截器更接近 bean 的另一个建议来修改MethodInvocation.arguments.

或者您可以子类化重试拦截器并覆盖该invoke方法。

两者都不是微不足道的,除非您对 Spring 代理有一些了解。

这是一种更简单的方法;如果您需要恢复而不是向调用者抛出最后一个异常,则需要做更多的工作。

@SpringBootApplication
@EnableRetry
public class So61486701Application {

    public static void main(String[] args) {
        SpringApplication.run(So61486701Application.class, args);
    }

    @Bean
    MethodInterceptor argumentChanger() {
        RetryTemplate retryTemplate = new RetryTemplate();
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3);
        FixedBackOffPolicy backOff = new FixedBackOffPolicy();
        backOff.setBackOffPeriod(1000L);
        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOff);
        return invocation -> {
            return retryTemplate.execute(context -> {
                if (context.getRetryCount() > 0) {
                    Object[] args = invocation.getArguments();
                    args[0] = ((Integer) args[0]) + 1;
                    args[1] = ((String) args[1]) + ((String) args[1]);
                }
                return invocation.proceed();
            });
        };
    }


    @Bean
    public ApplicationRunner runner(Foo foo) {
        return args -> foo.test(1, "foo.");
    }

}

@Component
class Foo {

     @Retryable(interceptor = "argumentChanger")
     public void test(int val, String str) {
        System.out.println(val + ":" + str);
        throw new RuntimeException();
     }

 }

推荐阅读