Reputation: 616
I have following method which is @Retryable:
@Retryable(value = HttpClientErrorException.class)
public Integer callToExternalService(DateTime start, DateTime end) throws MyException
My question is if I can modify input parameters each time method is under retry because I need to make a rest call with different values. Is there an option similar to @Recover
for this case?
Upvotes: 6
Views: 3075
Reputation: 174564
Not out of the box; you would need to add another advice closer to the bean than the retry interceptor to modify the MethodInvocation.arguments
.
Or you could subclass the retry interceptor and override the invoke
method.
Neither one is trivial, unless you have some knowledge about Spring proxies.
Here's a simpler way to do it; it will need a bit more work if you need to recover rather than throw the last exception to the caller.
@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();
}
}
Upvotes: 3