Изменяйте значения параметров при каждой попытке Spring Retry - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть следующий метод @Retryable:

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

Мой вопрос заключается в том, могу ли я изменять входные параметры каждый раз, когда метод повторяется, потому что мне нужно сделать вызов rest с другими значениями. Есть ли вариант, подобный @Recover для этого случая?

1 Ответ

0 голосов
/ 28 апреля 2020

Не из коробки; вам нужно добавить еще один совет ближе к компоненту, чем перехватчик повторов, чтобы изменить 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();
     }

 }
...