ExceptionRetryHandler implements RetryHandler { @Override public Object perform() throws Exception { boolean success = false; Object result = null; int retryCount = 0; while (!success) { try { if (retryCount > 0) { proxy.resetDelegate(); } result = operation(); success = true; } catch (Exception ex) { if (retryCount >= maxRetries || !isRetryable(ex)) { throw ex; } postFailure(ex, retryCount); try { Thread.sleep(getRetryInterval(retryCount)); } catch (InterruptedException ex1) { } retryCount = maxRetries < 0 ? maxRetries : retryCount + 1; } } return result; } private  ExceptionRetryHandler();  ExceptionRetryHandler(Class<?>[] exceptionClasses, ExceptionRetryingProxy proxy, RetrySchedule schedule, int maxRetries); @Override Object perform(); @Override void postFailure(Exception ex, int retryCount); @Override abstract Object operation(); long getRetryInterval(int retryCount);  }
@Test void testPerform() throws Exception { Object result = new ExceptionRetryHandler( exceptionClasses, proxy, schedule, 0) { @Override public Object operation() { return "Hi!"; } }.perform(); assertThat(result).isEqualTo("Hi!"); try { new ExceptionRetryHandler( exceptionClasses, proxy, schedule, 0) { @Override public Object operation() throws Exception { throw new Exception(); } }.perform(); } catch (Exception ex) { } assertThat(result).isEqualTo("Hi!"); }