To make processing more robust and less prone to failure, it sometimes helps to automatically retry a failed operation, in case it might succeed on a subsequent attempt. Errors that are susceptible to this kind of treatment are transient in nature. For example, a remote call to a web service or an RMI service that fails because of a network glitch or a DeadLockLoserException in a database update may resolve itself after a short wait. To automate the retry of such operations, Spring Retry has the RetryOperations strategy.
日常开发中,我们无法避免在调用远程Web服务时候因为网络故障或数据库死锁等原因导致的调用失败,有时候这些故障会在短暂的等待后自行恢复,而为了自动重试这些操作,我们可以选择引入 Spring Retry .
... 2019-09-0817:53:14.052 INFO 2200 --- [io-18080-exec-1] c.g.b.s.service.impl.UserServiceImpl : 2019-09-08T17:53:14.052 :start send message... 2019-09-0817:53:16.054 INFO 2200 --- [io-18080-exec-1] c.g.b.s.service.impl.UserServiceImpl : 2019-09-08T17:53:16.054 :start send message... 2019-09-0817:53:16.062 ERROR 2200 --- [io-18080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Send message is not allowed to be empty] with root cause
java.lang.IllegalArgumentException: Send message is not allowed to be empty ...
public Object invoke(final MethodInvocation invocation)throws Throwable {
String name; if (StringUtils.hasText(label)) { name = label; } else { name = invocation.getMethod().toGenericString(); } final String label = name;
RetryCallback<Object, Throwable> retryCallback = new RetryCallback<Object, Throwable>() {
public Object doWithRetry(RetryContext context)throws Exception {
context.setAttribute(RetryContext.NAME, label);
if (invocation instanceof ProxyMethodInvocation) { try { return ((ProxyMethodInvocation) invocation).invocableClone().proceed(); } catch (Exception e) { throw e; } catch (Error e) { throw e; } catch (Throwable e) { thrownew IllegalStateException(e); } } else { thrownew IllegalStateException("MethodInvocation of the wrong type detected - this should not happen with Spring AOP, so please raise an issue if you see this exception"); } }
};
if (recoverer != null) { ItemRecovererCallback recoveryCallback = new ItemRecovererCallback( invocation.getArguments(), recoverer); returnthis.retryOperations.execute(retryCallback, recoveryCallback); }