Merge branch '3.2.x' into master
Conflicts: gradle.properties spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java spring-context-support/src/main/java/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.java spring-core/src/main/java/org/springframework/core/convert/support/StringToEnumConverterFactory.java spring-core/src/main/java/org/springframework/core/env/ReadOnlySystemAttributesMap.java spring-jdbc/src/main/java/org/springframework/jdbc/datasource/LazyConnectionDataSourceProxy.java spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/AbstractLobHandler.java spring-web/src/main/java/org/springframework/http/client/BufferingClientHttpRequestWrapper.java spring-web/src/main/java/org/springframework/http/client/SimpleBufferingClientHttpRequest.java spring-web/src/main/java/org/springframework/http/converter/BufferedImageHttpMessageConverter.java spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -33,6 +33,7 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -228,4 +229,17 @@ public class SpringContextResourceAdapter implements ResourceAdapter {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return (obj instanceof SpringContextResourceAdapter &&
|
||||
ObjectUtils.nullSafeEquals(getContextConfigLocation(),
|
||||
((SpringContextResourceAdapter) obj).getContextConfigLocation()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(getContextConfigLocation());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -141,11 +141,11 @@ public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactor
|
||||
|
||||
|
||||
/**
|
||||
* Internal exception thrown when a ResourceExeption has been encountered
|
||||
* Internal exception thrown when a ResourceException has been encountered
|
||||
* during the endpoint invocation.
|
||||
* <p>Will only be used if the ResourceAdapter does not invoke the
|
||||
* endpoint's {@code beforeDelivery} and {@code afterDelivery}
|
||||
* directly, leavng it up to the concrete endpoint to apply those -
|
||||
* directly, leaving it up to the concrete endpoint to apply those -
|
||||
* and to handle any ResourceExceptions thrown from them.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -16,25 +16,24 @@
|
||||
|
||||
package org.springframework.transaction.interceptor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.transaction.NoTransactionException;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.TransactionSystemException;
|
||||
import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Base class for transactional aspects, such as the {@link TransactionInterceptor}
|
||||
* or an AspectJ aspect.
|
||||
@@ -233,6 +232,90 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General delegate for around-advice-based subclasses, delegating to several other template
|
||||
* methods on this class. Able to handle {@link CallbackPreferringPlatformTransactionManager}
|
||||
* as well as regular {@link PlatformTransactionManager} implementations.
|
||||
* @param method the Method being invoked
|
||||
* @param targetClass the target class that we're invoking the method on
|
||||
* @param invocation the callback to use for proceeding with the target invocation
|
||||
* @return the return value of the method, if any
|
||||
* @throws Throwable propagated from the target invocation
|
||||
*/
|
||||
protected Object invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation)
|
||||
throws Throwable {
|
||||
|
||||
// If the transaction attribute is null, the method is non-transactional.
|
||||
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
|
||||
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||
final String joinpointIdentification = methodIdentification(method, targetClass);
|
||||
|
||||
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
|
||||
// Standard transaction demarcation with getTransaction and commit/rollback calls.
|
||||
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
|
||||
Object retVal = null;
|
||||
try {
|
||||
// This is an around advice: Invoke the next interceptor in the chain.
|
||||
// This will normally result in a target object being invoked.
|
||||
retVal = invocation.proceedWithInvocation();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// target invocation exception
|
||||
completeTransactionAfterThrowing(txInfo, ex);
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
cleanupTransactionInfo(txInfo);
|
||||
}
|
||||
commitTransactionAfterReturning(txInfo);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
else {
|
||||
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
|
||||
try {
|
||||
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
|
||||
new TransactionCallback<Object>() {
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
|
||||
try {
|
||||
return invocation.proceedWithInvocation();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (txAttr.rollbackOn(ex)) {
|
||||
// A RuntimeException: will lead to a rollback.
|
||||
if (ex instanceof RuntimeException) {
|
||||
throw (RuntimeException) ex;
|
||||
}
|
||||
else {
|
||||
throw new ThrowableHolderException(ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// A normal return value: will lead to a commit.
|
||||
return new ThrowableHolder(ex);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
cleanupTransactionInfo(txInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Check result: It might indicate a Throwable to rethrow.
|
||||
if (result instanceof ThrowableHolder) {
|
||||
throw ((ThrowableHolder) result).getThrowable();
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (ThrowableHolderException ex) {
|
||||
throw ex.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the specific transaction manager to use for the given transaction.
|
||||
*/
|
||||
@@ -247,32 +330,11 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
else if (this.transactionManagerBeanName != null) {
|
||||
return this.beanFactory.getBean(this.transactionManagerBeanName, PlatformTransactionManager.class);
|
||||
}
|
||||
else if (this.beanFactory instanceof ListableBeanFactory) {
|
||||
return BeanFactoryUtils.beanOfTypeIncludingAncestors(((ListableBeanFactory) this.beanFactory), PlatformTransactionManager.class);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Cannot retrieve PlatformTransactionManager beans from non-listable BeanFactory: " + this.beanFactory);
|
||||
return this.beanFactory.getBean(PlatformTransactionManager.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction if necessary, based on the given method and class.
|
||||
* <p>Performs a default TransactionAttribute lookup for the given method.
|
||||
* @param method the method about to execute
|
||||
* @param targetClass the class that the method is being invoked on
|
||||
* @return a TransactionInfo object, whether or not a transaction was created.
|
||||
* The {@code hasTransaction()} method on TransactionInfo can be used to
|
||||
* tell if there was a transaction created.
|
||||
* @see #getTransactionAttributeSource()
|
||||
*/
|
||||
protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
|
||||
// If the transaction attribute is null, the method is non-transactional.
|
||||
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
|
||||
PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||
return createTransactionIfNecessary(tm, txAttr, methodIdentification(method, targetClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to return a String representation of this Method
|
||||
* for use in logging. Can be overridden in subclasses to provide a
|
||||
@@ -303,6 +365,26 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction if necessary, based on the given method and class.
|
||||
* <p>Performs a default TransactionAttribute lookup for the given method.
|
||||
* @param method the method about to execute
|
||||
* @param targetClass the class that the method is being invoked on
|
||||
* @return a TransactionInfo object, whether or not a transaction was created.
|
||||
* The {@code hasTransaction()} method on TransactionInfo can be used to
|
||||
* tell if there was a transaction created.
|
||||
* @see #getTransactionAttributeSource()
|
||||
* @deprecated in favor of
|
||||
* {@link #createTransactionIfNecessary(PlatformTransactionManager, TransactionAttribute, String)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
|
||||
// If the transaction attribute is null, the method is non-transactional.
|
||||
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
|
||||
PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||
return createTransactionIfNecessary(tm, txAttr, methodIdentification(method, targetClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction if necessary based on the given TransactionAttribute.
|
||||
* <p>Allows callers to perform custom TransactionAttribute lookups through
|
||||
@@ -533,4 +615,50 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple callback interface for proceeding with the target invocation.
|
||||
* Concrete interceptors/aspects adapt this to their invocation mechanism.
|
||||
*/
|
||||
protected interface InvocationCallback {
|
||||
|
||||
Object proceedWithInvocation() throws Throwable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal holder class for a Throwable, used as a return value
|
||||
* from a TransactionCallback (to be subsequently unwrapped again).
|
||||
*/
|
||||
private static class ThrowableHolder {
|
||||
|
||||
private final Throwable throwable;
|
||||
|
||||
public ThrowableHolder(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
public final Throwable getThrowable() {
|
||||
return this.throwable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal holder class for a Throwable, used as a RuntimeException to be
|
||||
* thrown from a TransactionCallback (and subsequently unwrapped again).
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
private static class ThrowableHolderException extends RuntimeException {
|
||||
|
||||
public ThrowableHolderException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getCause().toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -16,22 +16,18 @@
|
||||
|
||||
package org.springframework.transaction.interceptor;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
|
||||
/**
|
||||
* AOP Alliance MethodInterceptor for declarative transaction
|
||||
* management using the common Spring transaction infrastructure
|
||||
@@ -40,7 +36,7 @@ import org.springframework.transaction.support.TransactionCallback;
|
||||
* <p>Derives from the {@link TransactionAspectSupport} class which
|
||||
* contains the integration with Spring's underlying transaction API.
|
||||
* TransactionInterceptor simply calls the relevant superclass methods
|
||||
* such as {@link #createTransactionIfNecessary} in the correct order.
|
||||
* such as {@link #invokeWithinTransaction} in the correct order.
|
||||
*
|
||||
* <p>TransactionInterceptors are thread-safe.
|
||||
*
|
||||
@@ -94,76 +90,12 @@ public class TransactionInterceptor extends TransactionAspectSupport implements
|
||||
// as well as the method, which may be from an interface.
|
||||
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
|
||||
|
||||
// If the transaction attribute is null, the method is non-transactional.
|
||||
final TransactionAttribute txAttr =
|
||||
getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass);
|
||||
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||
final String joinpointIdentification = methodIdentification(invocation.getMethod(), targetClass);
|
||||
|
||||
if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
|
||||
// Standard transaction demarcation with getTransaction and commit/rollback calls.
|
||||
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
|
||||
Object retVal = null;
|
||||
try {
|
||||
// This is an around advice: Invoke the next interceptor in the chain.
|
||||
// This will normally result in a target object being invoked.
|
||||
retVal = invocation.proceed();
|
||||
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
|
||||
return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
|
||||
public Object proceedWithInvocation() throws Throwable {
|
||||
return invocation.proceed();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// target invocation exception
|
||||
completeTransactionAfterThrowing(txInfo, ex);
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
cleanupTransactionInfo(txInfo);
|
||||
}
|
||||
commitTransactionAfterReturning(txInfo);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
else {
|
||||
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
|
||||
try {
|
||||
Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr,
|
||||
new TransactionCallback<Object>() {
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
|
||||
try {
|
||||
return invocation.proceed();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (txAttr.rollbackOn(ex)) {
|
||||
// A RuntimeException: will lead to a rollback.
|
||||
if (ex instanceof RuntimeException) {
|
||||
throw (RuntimeException) ex;
|
||||
}
|
||||
else {
|
||||
throw new ThrowableHolderException(ex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// A normal return value: will lead to a commit.
|
||||
return new ThrowableHolder(ex);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
cleanupTransactionInfo(txInfo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Check result: It might indicate a Throwable to rethrow.
|
||||
if (result instanceof ThrowableHolder) {
|
||||
throw ((ThrowableHolder) result).getThrowable();
|
||||
}
|
||||
else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (ThrowableHolderException ex) {
|
||||
throw ex.getCause();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -195,39 +127,4 @@ public class TransactionInterceptor extends TransactionAspectSupport implements
|
||||
setBeanFactory((BeanFactory) ois.readObject());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal holder class for a Throwable, used as a return value
|
||||
* from a TransactionCallback (to be subsequently unwrapped again).
|
||||
*/
|
||||
private static class ThrowableHolder {
|
||||
|
||||
private final Throwable throwable;
|
||||
|
||||
public ThrowableHolder(Throwable throwable) {
|
||||
this.throwable = throwable;
|
||||
}
|
||||
|
||||
public final Throwable getThrowable() {
|
||||
return this.throwable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal holder class for a Throwable, used as a RuntimeException to be
|
||||
* thrown from a TransactionCallback (and subsequently unwrapped again).
|
||||
*/
|
||||
private static class ThrowableHolderException extends RuntimeException {
|
||||
|
||||
public ThrowableHolderException(Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getCause().toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -176,8 +176,8 @@ public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBe
|
||||
/**
|
||||
* This callback is optional: If running in a BeanFactory and no transaction
|
||||
* manager has been set explicitly, a single matching bean of type
|
||||
* PlatformTransactionManager will be fetched from the BeanFactory.
|
||||
* @see org.springframework.beans.factory.BeanFactoryUtils#beanOfTypeIncludingAncestors
|
||||
* {@link PlatformTransactionManager} will be fetched from the BeanFactory.
|
||||
* @see org.springframework.beans.factory.BeanFactory#getBean(Class)
|
||||
* @see org.springframework.transaction.PlatformTransactionManager
|
||||
*/
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
|
||||
Reference in New Issue
Block a user