RetryTemplateAspect implements BeanFactoryAware { @Around("@annotation(retryTemplateAnnotation)") public Object retry(final ProceedingJoinPoint pjp, final RetryTemplate retryTemplateAnnotation) throws Throwable { final String name = retryTemplateAnnotation.name(); final String recoveryCallbackName = retryTemplateAnnotation.recoveryCallbackName(); org.springframework.retry.support.RetryTemplate retryTemplate = beanFactory.getBean(name, org.springframework.retry.support.RetryTemplate.class); RecoveryCallback<Object> recoveryCallback = null; if (! Strings.isNullOrEmpty(recoveryCallbackName)) { recoveryCallback = beanFactory.getBean(recoveryCallbackName, org.springframework.retry.RecoveryCallback.class); } if (logger.isDebugEnabled()) { logger.debug("Have @RetryTemplate method with retryTemplate name {} and callback name {}, " + "wrapping call on method {} of target object {}", new Object[]{ name, recoveryCallbackName, pjp.getSignature().getName(), pjp.getTarget()}); } return retryTemplate.execute( new RetryCallback<Object, Exception>() { public Object doWithRetry(RetryContext context) throws Exception { try { return pjp.proceed(); } catch (Error e) { throw e; } catch (Exception e) { throw e; } catch (Throwable e) { throw new RuntimeException(e); } } }, recoveryCallback); } RetryTemplateAspect(); @Autowired @Required void setBeanFactory(BeanFactory beanFactory); @Around("@annotation(retryTemplateAnnotation)") Object retry(final ProceedingJoinPoint pjp,
                        final RetryTemplate retryTemplateAnnotation);  }
@Test(expected = NoSuchBeanDefinitionException.class) public void testRetryWithMissingBean() throws Throwable { Mockito.doThrow(new NoSuchBeanDefinitionException("")).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); try { aspect.retry(mockPjp, mockAnnotation); } finally { Mockito.verify(mockPjp, Mockito.never()).proceed(); } }
@Test(expected = BeanNotOfRequiredTypeException.class) public void testRetryWithWrongBeanType() throws Throwable { Mockito.doThrow(new BeanNotOfRequiredTypeException("", String.class, String.class)).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); try { aspect.retry(mockPjp, mockAnnotation); } finally { Mockito.verify(mockPjp, Mockito.never()).proceed(); } }
@Test public void testRetry() throws Throwable { org.springframework.retry.support.RetryTemplate template = new org.springframework.retry.support.RetryTemplate(); Mockito.doReturn(template).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); Mockito.doReturn("a").when(mockPjp).proceed(); Assert.assertEquals("a", aspect.retry(mockPjp, mockAnnotation)); Mockito.verify(mockPjp, Mockito.times(1)).proceed(); }
@Test public void testRetryExceptionWithRecovery() throws Throwable { Mockito.doReturn(TEST_RETRY_TEMPLATE_RECOVERY).when(mockAnnotation).recoveryCallbackName(); org.springframework.retry.support.RetryTemplate template = new org.springframework.retry.support.RetryTemplate(); Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<Class<? extends Throwable>, Boolean>(); exceptionMap.put(RuntimeException.class, Boolean.TRUE); template.setRetryPolicy(new SimpleRetryPolicy(1, exceptionMap)); Mockito.doReturn(template).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); Mockito.doReturn(recoveryCallback).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE_RECOVERY, RecoveryCallback.class); Mockito.doThrow(new RuntimeException()).when(mockPjp).proceed(); Mockito.doReturn("a").when(recoveryCallback).recover(Mockito.any(RetryContext.class)); Assert.assertEquals("a", aspect.retry(mockPjp, mockAnnotation)); Mockito.verify(mockPjp, Mockito.times(1)).proceed(); }
@Test(expected=RuntimeException.class) public void testRetryExceptionWithoutRecovery() throws Throwable { org.springframework.retry.support.RetryTemplate template = new org.springframework.retry.support.RetryTemplate(); Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<Class<? extends Throwable>, Boolean>(); exceptionMap.put(RuntimeException.class, Boolean.TRUE); template.setRetryPolicy(new SimpleRetryPolicy(1, exceptionMap)); Mockito.doReturn(template).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); Mockito.doReturn(null).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE_RECOVERY, RecoveryCallback.class); Mockito.doThrow(new RuntimeException()).when(mockPjp).proceed(); try { aspect.retry(mockPjp, mockAnnotation); } finally { Mockito.verify(mockPjp, Mockito.times(1)).proceed(); } }
@Test(expected=OutOfMemoryError.class) public void testRetryErrorWithoutRecovery() throws Throwable { org.springframework.retry.support.RetryTemplate template = new org.springframework.retry.support.RetryTemplate(); Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<Class<? extends Throwable>, Boolean>(); exceptionMap.put(RuntimeException.class, Boolean.TRUE); template.setRetryPolicy(new SimpleRetryPolicy(1, exceptionMap)); Mockito.doReturn(template).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); Mockito.doReturn(null).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE_RECOVERY, RecoveryCallback.class); Mockito.doThrow(new OutOfMemoryError()).when(mockPjp).proceed(); try { aspect.retry(mockPjp, mockAnnotation); } finally { Mockito.verify(mockPjp, Mockito.times(1)).proceed(); } }
@Test(expected=RuntimeException.class) public void testRetryThrowableWithoutRecovery() throws Throwable { org.springframework.retry.support.RetryTemplate template = new org.springframework.retry.support.RetryTemplate(); Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<Class<? extends Throwable>, Boolean>(); exceptionMap.put(RuntimeException.class, Boolean.TRUE); template.setRetryPolicy(new SimpleRetryPolicy(1, exceptionMap)); Mockito.doReturn(template).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE, org.springframework.retry.support.RetryTemplate.class); Mockito.doReturn(null).when(beanFactory) .getBean(TEST_RETRY_TEMPLATE_RECOVERY, RecoveryCallback.class); Mockito.doThrow(new Throwable("")).when(mockPjp).proceed(); try { aspect.retry(mockPjp, mockAnnotation); } finally { Mockito.verify(mockPjp, Mockito.times(1)).proceed(); } }