Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2006-2007 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.springframework.batch.retry.interceptor;
 
 
A org.aopalliance.intercept.MethodInterceptor that can be used to automatically retry calls to a method on a service if it fails. The argument to the service method is treated as an item to be remembered in case the call fails. So the retry operation is stateful, and the item that failed is tracked by its unique key (via MethodArgumentsKeyGenerator) until the retry is exhausted, at which point the MethodInvocationRecoverer is called.
The main use case for this is where the service is transactional, via a transaction interceptor on the interceptor chain. In this case the retry (and recovery on exhausted) always happens in a new transaction.
The injected org.springframework.batch.retry.RetryOperations is used to control the number of retries. By default it will retry a fixed number of times, according to the defaults in org.springframework.batch.retry.support.RetryTemplate.

Author(s):
Dave Syer
 
 
 	private transient Log logger = LogFactory.getLog(getClass());
 
 
 	private MethodInvocationRecoverer<? extends Objectrecoverer;
 
 
 
 	public void setRetryOperations(RetryOperations retryTemplate) {
 		Assert.notNull(retryTemplate"'retryOperations' cannot be null.");
 		this. = retryTemplate;
 	}

 
 		super();
 		RetryTemplate retryTemplate = new RetryTemplate();
 		retryTemplate.setRetryPolicy(new NeverRetryPolicy());
 		 = retryTemplate;
 	}

Public setter for the MethodInvocationRecoverer to use if the retry is exhausted. The recoverer should be able to return an object of the same type as the target object because its return value will be used to return to the caller in the case of a recovery.
If no recoverer is set then an exhausted retry will result in an org.springframework.batch.retry.ExhaustedRetryException.

Parameters:
recoverer the MethodInvocationRecoverer to set
 
 	public void setRecoverer(MethodInvocationRecoverer<? extends Objectrecoverer) {
 		this. = recoverer;
 	}
 
 	public void setKeyGenerator(MethodArgumentsKeyGenerator keyGenerator) {
 		this. = keyGenerator;
 	}

Public setter for the NewMethodArgumentsIdentifier. Only set this if the arguments to the intercepted method can be inspected to find out if they have never been processed before.

Parameters:
newMethodArgumentsIdentifier the NewMethodArgumentsIdentifier to set
	public void setNewItemIdentifier(NewMethodArgumentsIdentifier newMethodArgumentsIdentifier) {
		this. = newMethodArgumentsIdentifier;
	}

Wrap the method invocation in a stateful retry with the policy and other helpers provided. If there is a failure the exception will generally be re-thrown. The only time it is not re-thrown is when retry is exhausted and the recovery path is taken (though the MethodInvocationRecoverer provided if there is one). In that case the value returned from the method invocation will be the value returned by the recoverer (so the return type for that should be the same as the intercepted method).

	public Object invoke(final MethodInvocation invocationthrows Throwable {
		.debug("Executing proxied method in stateful retry: " + invocation.getStaticPart() + "("
				+ ObjectUtils.getIdentityHexString(invocation) + ")");
		Object[] args = invocation.getArguments();
		Assert.state(args.length > 0, "Stateful retry applied to method that takes no arguments: "
invocation.getStaticPart());
		Object arg = args;
		if (args.length == 1) {
			arg = args[0];
		}
		final Object item = arg;
		RetryState retryState = new DefaultRetryState( != null ? .getKey(args) : item,
				new ItemRecovererCallback(args), retryState);
		.debug("Exiting proxied method in stateful retry with result: (" + result + ")");
		return result;
	}

Author(s):
Dave Syer
	private static final class MethodInvocationRetryCallback implements RetryCallback<Object> {
		private final MethodInvocation invocation;

Parameters:
invocation
			this. = invocation;
		}
		public Object doWithRetry(RetryContext contextthrows Exception {
			try {
			}
			catch (Exception e) {
				throw e;
			}
			catch (Error e) {
				throw e;
			}
			catch (Throwable e) {
				throw new IllegalStateException(e);
			}
		}
	}

Author(s):
Dave Syer
	private static final class ItemRecovererCallback implements RecoveryCallback<Object> {
		private final Object[] args;
		private final MethodInvocationRecoverer<? extends Objectrecoverer;

Parameters:
args the item that failed.
		private ItemRecovererCallback(Object[] argsMethodInvocationRecoverer<? extends Objectrecoverer) {
			this. = Arrays.asList(args).toArray();
			this. = recoverer;
		}
		public Object recover(RetryContext context) {
			if ( != null) {
				return .recover(context.getLastThrowable());
			}
			throw new ExhaustedRetryException("Retry was exhausted but there was no recovery path.");
		}
	}
New to GrepCode? Check out our FAQ X