summaryrefslogtreecommitdiff
path: root/spring-aop/src/main/java/org/springframework
diff options
context:
space:
mode:
Diffstat (limited to 'spring-aop/src/main/java/org/springframework')
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java41
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java5
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java5
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java5
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java4
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java4
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java2
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/SimpleAspectInstanceFactory.java8
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java7
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java25
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java6
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java27
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java16
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/MetadataAwareAspectInstanceFactory.java9
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java5
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java4
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SimpleMetadataAwareAspectInstanceFactory.java7
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java12
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/config/AopConfigUtils.java4
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java25
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java40
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java13
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java5
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java4
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AutoProxyUtils.java2
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java2
-rw-r--r--spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java35
27 files changed, 258 insertions, 64 deletions
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java
index 71bd31d9..c7575168 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java
@@ -16,6 +16,9 @@
package org.springframework.aop.aspectj;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
@@ -55,7 +58,8 @@ import org.springframework.util.StringUtils;
* @author Ramnivas Laddad
* @since 2.0
*/
-public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation {
+@SuppressWarnings("serial")
+public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedenceInformation, Serializable {
/**
* Key used in ReflectiveMethodInvocation userAtributes map for the current joinpoint.
@@ -86,10 +90,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
- protected final Method aspectJAdviceMethod;
+ private final Class<?> declaringClass;
- /** The total number of arguments we have to populate on advice dispatch */
- private final int adviceInvocationArgumentCount;
+ private final String methodName;
+
+ private final Class<?>[] parameterTypes;
+
+ protected transient Method aspectJAdviceMethod;
private final AspectJExpressionPointcut pointcut;
@@ -154,8 +161,10 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory) {
Assert.notNull(aspectJAdviceMethod, "Advice method must not be null");
+ this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
+ this.methodName = aspectJAdviceMethod.getName();
+ this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
- this.adviceInvocationArgumentCount = this.aspectJAdviceMethod.getParameterTypes().length;
this.pointcut = pointcut;
this.aspectInstanceFactory = aspectInstanceFactory;
}
@@ -359,11 +368,11 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
*/
public synchronized final void calculateArgumentBindings() {
// The simple case... nothing to bind.
- if (this.argumentsIntrospected || this.adviceInvocationArgumentCount == 0) {
+ if (this.argumentsIntrospected || this.parameterTypes.length == 0) {
return;
}
- int numUnboundArgs = this.adviceInvocationArgumentCount;
+ int numUnboundArgs = this.parameterTypes.length;
Class<?>[] parameterTypes = this.aspectJAdviceMethod.getParameterTypes();
if (maybeBindJoinPoint(parameterTypes[0]) || maybeBindProceedingJoinPoint(parameterTypes[0])) {
numUnboundArgs--;
@@ -462,7 +471,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
// So we match in number...
- int argumentIndexOffset = this.adviceInvocationArgumentCount - numArgumentsLeftToBind;
+ int argumentIndexOffset = this.parameterTypes.length - numArgumentsLeftToBind;
for (int i = argumentIndexOffset; i < this.argumentNames.length; i++) {
this.argumentBindings.put(this.argumentNames[i], i);
}
@@ -543,7 +552,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
calculateArgumentBindings();
// AMC start
- Object[] adviceInvocationArgs = new Object[this.adviceInvocationArgumentCount];
+ Object[] adviceInvocationArgs = new Object[this.parameterTypes.length];
int numBound = 0;
if (this.joinPointArgumentIndex != -1) {
@@ -580,8 +589,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
}
}
- if (numBound != this.adviceInvocationArgumentCount) {
- throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount +
+ if (numBound != this.parameterTypes.length) {
+ throw new IllegalStateException("Required to bind " + this.parameterTypes.length +
" arguments, but only bound " + numBound + " (JoinPointMatch " +
(jpMatch == null ? "was NOT" : "WAS") + " bound in invocation)");
}
@@ -664,6 +673,16 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
"aspect name '" + this.aspectName + "'";
}
+ private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
+ inputStream.defaultReadObject();
+ try {
+ this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
+ }
+ catch (NoSuchMethodException ex) {
+ throw new IllegalStateException("Failed to find advice method on deserialization", ex);
+ }
+ }
+
/**
* MethodMatcher that excludes the specified advice method.
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java
index a1900b89..3de3c25a 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java
@@ -16,6 +16,7 @@
package org.springframework.aop.aspectj;
+import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
@@ -29,7 +30,9 @@ import org.springframework.aop.AfterAdvice;
* @author Rod Johnson
* @since 2.0
*/
-public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
+@SuppressWarnings("serial")
+public class AspectJAfterAdvice extends AbstractAspectJAdvice
+ implements MethodInterceptor, AfterAdvice, Serializable {
public AspectJAfterAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java
index 3a852bdb..92f9cb4a 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java
@@ -16,6 +16,7 @@
package org.springframework.aop.aspectj;
+import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
@@ -32,7 +33,9 @@ import org.springframework.util.TypeUtils;
* @author Ramnivas Laddad
* @since 2.0
*/
-public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice {
+@SuppressWarnings("serial")
+public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
+ implements AfterReturningAdvice, AfterAdvice, Serializable {
public AspectJAfterReturningAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java
index be74c7e4..fcf89a12 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java
@@ -16,6 +16,7 @@
package org.springframework.aop.aspectj;
+import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
@@ -29,7 +30,9 @@ import org.springframework.aop.AfterAdvice;
* @author Rod Johnson
* @since 2.0
*/
-public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice {
+@SuppressWarnings("serial")
+public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
+ implements MethodInterceptor, AfterAdvice, Serializable {
public AspectJAfterThrowingAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java
index 3efefd27..66f3b03b 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java
@@ -16,6 +16,7 @@
package org.springframework.aop.aspectj;
+import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
@@ -33,7 +34,8 @@ import org.springframework.aop.ProxyMethodInvocation;
* @author Juergen Hoeller
* @since 2.0
*/
-public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor {
+@SuppressWarnings("serial")
+public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
public AspectJAroundAdvice(
Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java
index 65a5dce1..b1834566 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java
@@ -16,6 +16,7 @@
package org.springframework.aop.aspectj;
+import java.io.Serializable;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
@@ -27,7 +28,8 @@ import org.springframework.aop.MethodBeforeAdvice;
* @author Adrian Colyer
* @since 2.0
*/
-public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice {
+@SuppressWarnings("serial")
+public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {
public AspectJMethodBeforeAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java
index 3272b922..47e46155 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/DeclareParentsAdvisor.java
@@ -65,7 +65,7 @@ public class DeclareParentsAdvisor implements IntroductionAdvisor {
/**
* Private constructor to share common code between impl-based delegate and reference-based delegate
- * (cannot use method such as init() to share common code, due the the use of final fields)
+ * (cannot use method such as init() to share common code, due the use of final fields)
* @param interfaceType static field defining the introduction
* @param typePattern type pattern the introduction is restricted to
* @param implementationClass implementation class
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/SimpleAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/SimpleAspectInstanceFactory.java
index f1275dae..5d413bd6 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/SimpleAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/SimpleAspectInstanceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -55,10 +55,12 @@ public class SimpleAspectInstanceFactory implements AspectInstanceFactory {
return this.aspectClass.newInstance();
}
catch (InstantiationException ex) {
- throw new AopConfigException("Unable to instantiate aspect class [" + this.aspectClass.getName() + "]", ex);
+ throw new AopConfigException(
+ "Unable to instantiate aspect class: " + this.aspectClass.getName(), ex);
}
catch (IllegalAccessException ex) {
- throw new AopConfigException("Cannot access element class [" + this.aspectClass.getName() + "]", ex);
+ throw new AopConfigException(
+ "Could not access aspect constructor: " + this.aspectClass.getName(), ex);
}
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java
index 1e8f723e..d311f620 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2015 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,6 +16,8 @@
package org.springframework.aop.aspectj;
+import java.io.Serializable;
+
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
@@ -29,7 +31,8 @@ import org.springframework.util.Assert;
* @since 2.0
* @see SimpleAspectInstanceFactory
*/
-public class SingletonAspectInstanceFactory implements AspectInstanceFactory {
+@SuppressWarnings("serial")
+public class SingletonAspectInstanceFactory implements AspectInstanceFactory, Serializable {
private final Object aspectInstance;
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java
index d20e5222..dd8823ec 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java
@@ -16,6 +16,10 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.AjType;
import org.aspectj.lang.reflect.AjTypeSystem;
@@ -40,7 +44,8 @@ import org.springframework.aop.support.ComposablePointcut;
* @since 2.0
* @see org.springframework.aop.aspectj.AspectJExpressionPointcut
*/
-public class AspectMetadata {
+@SuppressWarnings("serial")
+public class AspectMetadata implements Serializable {
/**
* The name of this aspect as defined to Spring (the bean name) -
@@ -50,9 +55,16 @@ public class AspectMetadata {
private final String aspectName;
/**
+ * The aspect class, stored separately for re-resolution of the
+ * corresponding AjType on deserialization.
+ */
+ private final Class<?> aspectClass;
+
+ /**
* AspectJ reflection information (AspectJ 5 / Java 5 specific).
+ * Re-resolved on deserialization since it isn't serializable itself.
*/
- private final AjType<?> ajType;
+ private transient AjType<?> ajType;
/**
* Spring AOP pointcut corresponding to the per clause of the
@@ -86,6 +98,7 @@ public class AspectMetadata {
if (ajType.getDeclarePrecedence().length > 0) {
throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP");
}
+ this.aspectClass = ajType.getJavaClass();
this.ajType = ajType;
switch (this.ajType.getPerClause().getKind()) {
@@ -132,7 +145,7 @@ public class AspectMetadata {
* Return the aspect class.
*/
public Class<?> getAspectClass() {
- return this.ajType.getJavaClass();
+ return this.aspectClass;
}
/**
@@ -173,4 +186,10 @@ public class AspectMetadata {
return (isPerThisOrPerTarget() || isPerTypeWithin());
}
+
+ private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
+ inputStream.defaultReadObject();
+ this.ajType = AjTypeSystem.getAjType(this.aspectClass);
+ }
+
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java
index 713fb44f..f68fea56 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java
@@ -16,6 +16,8 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.Serializable;
+
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.Ordered;
@@ -38,7 +40,8 @@ import org.springframework.util.ClassUtils;
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
-public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory {
+@SuppressWarnings("serial")
+public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory, Serializable {
private final BeanFactory beanFactory;
@@ -92,6 +95,7 @@ public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInst
return this.aspectMetadata;
}
+ @Override
public Object getAspectCreationMutex() {
return (this.beanFactory instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) this.beanFactory).getSingletonMutex() : this);
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java
index 750a1eb2..27d3a9ba 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java
@@ -16,6 +16,9 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
import java.lang.reflect.Method;
import org.aopalliance.aop.Advice;
@@ -37,12 +40,19 @@ import org.springframework.aop.support.Pointcuts;
* @author Juergen Hoeller
* @since 2.0
*/
+@SuppressWarnings("serial")
class InstantiationModelAwarePointcutAdvisorImpl
- implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation {
+ implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {
private final AspectJExpressionPointcut declaredPointcut;
- private final Method aspectJAdviceMethod;
+ private final Class<?> declaringClass;
+
+ private final String methodName;
+
+ private final Class<?>[] parameterTypes;
+
+ private transient Method aspectJAdviceMethod;
private final AspectJAdvisorFactory aspectJAdvisorFactory;
@@ -68,6 +78,9 @@ class InstantiationModelAwarePointcutAdvisorImpl
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
+ this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
+ this.methodName = aspectJAdviceMethod.getName();
+ this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
@@ -227,6 +240,16 @@ class InstantiationModelAwarePointcutAdvisorImpl
}
+ private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
+ inputStream.defaultReadObject();
+ try {
+ this.aspectJAdviceMethod = this.declaringClass.getMethod(this.methodName, this.parameterTypes);
+ }
+ catch (NoSuchMethodException ex) {
+ throw new IllegalStateException("Failed to find advice method on deserialization", ex);
+ }
+ }
+
/**
* Pointcut implementation that changes its behaviour when the advice is instantiated.
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java
index 78df5465..3e76fb47 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java
@@ -16,6 +16,8 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.Serializable;
+
import org.springframework.util.Assert;
/**
@@ -25,7 +27,8 @@ import org.springframework.util.Assert;
* @author Juergen Hoeller
* @since 2.0
*/
-public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory {
+@SuppressWarnings("serial")
+public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwareAspectInstanceFactory, Serializable {
private final MetadataAwareAspectInstanceFactory maaif;
@@ -45,11 +48,7 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
@Override
public Object getAspectInstance() {
if (this.materialized == null) {
- Object mutex = this;
- if (this.maaif instanceof BeanFactoryAspectInstanceFactory) {
- mutex = ((BeanFactoryAspectInstanceFactory) this.maaif).getAspectCreationMutex();
- }
- synchronized (mutex) {
+ synchronized (this.maaif.getAspectCreationMutex()) {
if (this.materialized == null) {
this.materialized = this.maaif.getAspectInstance();
}
@@ -73,6 +72,11 @@ public class LazySingletonAspectInstanceFactoryDecorator implements MetadataAwar
}
@Override
+ public Object getAspectCreationMutex() {
+ return this.maaif.getAspectCreationMutex();
+ }
+
+ @Override
public int getOrder() {
return this.maaif.getOrder();
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/MetadataAwareAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/MetadataAwareAspectInstanceFactory.java
index cb9a77d4..a001efbc 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/MetadataAwareAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/MetadataAwareAspectInstanceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -39,4 +39,11 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
*/
AspectMetadata getAspectMetadata();
+ /**
+ * Return the best possible creation mutex for this factory.
+ * @return the mutex object (never {@code null})
+ * @since 4.3
+ */
+ Object getAspectCreationMutex();
+
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java
index fc2978a9..e1e17155 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java
@@ -16,6 +16,8 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.Serializable;
+
import org.springframework.beans.factory.BeanFactory;
/**
@@ -32,7 +34,8 @@ import org.springframework.beans.factory.BeanFactory;
* @see org.springframework.beans.factory.BeanFactory
* @see LazySingletonAspectInstanceFactoryDecorator
*/
-public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory {
+@SuppressWarnings("serial")
+public class PrototypeAspectInstanceFactory extends BeanFactoryAspectInstanceFactory implements Serializable {
/**
* Create a PrototypeAspectInstanceFactory. AspectJ will be called to
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java
index 1a354930..ce139f71 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java
@@ -16,6 +16,7 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -65,7 +66,8 @@ import org.springframework.util.comparator.InstanceComparator;
* @author Phillip Webb
* @since 2.0
*/
-public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory {
+@SuppressWarnings("serial")
+public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
private static final Comparator<Method> METHOD_COMPARATOR;
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SimpleMetadataAwareAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SimpleMetadataAwareAspectInstanceFactory.java
index 5b8113e7..2aa2431a 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SimpleMetadataAwareAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SimpleMetadataAwareAspectInstanceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -51,6 +51,11 @@ public class SimpleMetadataAwareAspectInstanceFactory extends SimpleAspectInstan
}
@Override
+ public Object getAspectCreationMutex() {
+ return this;
+ }
+
+ @Override
protected int getOrderForAspectClass(Class<?> aspectClass) {
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java
index 0f83e6c2..15edfbbd 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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,6 +16,8 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.Serializable;
+
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.OrderUtils;
@@ -30,8 +32,9 @@ import org.springframework.core.annotation.OrderUtils;
* @since 2.0
* @see SimpleMetadataAwareAspectInstanceFactory
*/
+@SuppressWarnings("serial")
public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspectInstanceFactory
- implements MetadataAwareAspectInstanceFactory {
+ implements MetadataAwareAspectInstanceFactory, Serializable {
private final AspectMetadata metadata;
@@ -53,6 +56,11 @@ public class SingletonMetadataAwareAspectInstanceFactory extends SingletonAspect
}
@Override
+ public Object getAspectCreationMutex() {
+ return this;
+ }
+
+ @Override
protected int getOrderForAspectClass(Class<?> aspectClass) {
return OrderUtils.getOrder(aspectClass, Ordered.LOWEST_PRECEDENCE);
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/config/AopConfigUtils.java b/spring-aop/src/main/java/org/springframework/aop/config/AopConfigUtils.java
index d3f199c5..c2271500 100644
--- a/spring-aop/src/main/java/org/springframework/aop/config/AopConfigUtils.java
+++ b/spring-aop/src/main/java/org/springframework/aop/config/AopConfigUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -97,7 +97,7 @@ public abstract class AopConfigUtils {
}
}
- static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
+ public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java
index 9b3b3074..40940374 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -586,7 +586,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
* Simple wrapper class around a Method. Used as the key when
* caching methods, for efficient equals and hashCode comparisons.
*/
- private static class MethodCacheKey {
+ private static final class MethodCacheKey implements Comparable<MethodCacheKey> {
private final Method method;
@@ -599,17 +599,28 @@ public class AdvisedSupport extends ProxyConfig implements Advised {
@Override
public boolean equals(Object other) {
- if (other == this) {
- return true;
- }
- MethodCacheKey otherKey = (MethodCacheKey) other;
- return (this.method == otherKey.method);
+ return (this == other || (other instanceof MethodCacheKey &&
+ this.method == ((MethodCacheKey) other).method));
}
@Override
public int hashCode() {
return this.hashCode;
}
+
+ @Override
+ public String toString() {
+ return this.method.toString();
+ }
+
+ @Override
+ public int compareTo(MethodCacheKey other) {
+ int result = this.method.getName().compareTo(other.method.getName());
+ if (result == 0) {
+ result = this.method.toString().compareTo(other.method.toString());
+ }
+ return result;
+ }
}
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java
index 4e063d2b..15535a5e 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/AopProxyUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -26,6 +26,7 @@ import org.springframework.aop.TargetClassAware;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.target.SingletonTargetSource;
+import org.springframework.core.DecoratingProxy;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -78,11 +79,29 @@ public abstract class AopProxyUtils {
* <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
* {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
* {@link org.springframework.aop.SpringProxy} marker interface.
+ * @param advised the proxy config
* @return the complete set of interfaces to proxy
+ * @see SpringProxy
* @see Advised
- * @see org.springframework.aop.SpringProxy
*/
public static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised) {
+ return completeProxiedInterfaces(advised, false);
+ }
+
+ /**
+ * Determine the complete set of interfaces to proxy for the given AOP configuration.
+ * <p>This will always add the {@link Advised} interface unless the AdvisedSupport's
+ * {@link AdvisedSupport#setOpaque "opaque"} flag is on. Always adds the
+ * {@link org.springframework.aop.SpringProxy} marker interface.
+ * @param advised the proxy config
+ * @param decoratingProxy whether to expose the {@link DecoratingProxy} interface
+ * @return the complete set of interfaces to proxy
+ * @since 4.3
+ * @see SpringProxy
+ * @see Advised
+ * @see DecoratingProxy
+ */
+ static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
@@ -99,6 +118,7 @@ public abstract class AopProxyUtils {
}
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
+ boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
int nonUserIfcCount = 0;
if (addSpringProxy) {
nonUserIfcCount++;
@@ -106,13 +126,22 @@ public abstract class AopProxyUtils {
if (addAdvised) {
nonUserIfcCount++;
}
+ if (addDecoratingProxy) {
+ nonUserIfcCount++;
+ }
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
+ int index = specifiedInterfaces.length;
if (addSpringProxy) {
- proxiedInterfaces[specifiedInterfaces.length] = SpringProxy.class;
+ proxiedInterfaces[index] = SpringProxy.class;
+ index++;
}
if (addAdvised) {
- proxiedInterfaces[proxiedInterfaces.length - 1] = Advised.class;
+ proxiedInterfaces[index] = Advised.class;
+ index++;
+ }
+ if (addDecoratingProxy) {
+ proxiedInterfaces[index] = DecoratingProxy.class;
}
return proxiedInterfaces;
}
@@ -134,6 +163,9 @@ public abstract class AopProxyUtils {
if (proxy instanceof Advised) {
nonUserIfcCount++;
}
+ if (proxy instanceof DecoratingProxy) {
+ nonUserIfcCount++;
+ }
Class<?>[] userInterfaces = new Class<?>[proxyInterfaces.length - nonUserIfcCount];
System.arraycopy(proxyInterfaces, 0, userInterfaces, 0, userInterfaces.length);
Assert.notEmpty(userInterfaces, "JDK proxy must implement one or more interfaces");
diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java
index e98c3085..1f90b0b5 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -30,6 +30,7 @@ import org.springframework.aop.AopInvocationException;
import org.springframework.aop.RawTargetAccess;
import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils;
+import org.springframework.core.DecoratingProxy;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -116,7 +117,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
- Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
+ Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
@@ -164,11 +165,15 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
- if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
+ else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
- if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
+ else if (method.getDeclaringClass() == DecoratingProxy.class) {
+ // There is only getDecoratedClass() declared -> dispatch to proxy config.
+ return AopProxyUtils.ultimateTargetClass(this.advised);
+ }
+ else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java
index af1cf603..a94c53b1 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/ProxyProcessorSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -139,7 +139,8 @@ public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanC
* @return whether the given interface is an internal language interface
*/
protected boolean isInternalLanguageInterface(Class<?> ifc) {
- return ifc.getName().equals("groovy.lang.GroovyObject");
+ return (ifc.getName().equals("groovy.lang.GroovyObject") ||
+ ifc.getName().endsWith(".cglib.proxy.Factory"));
}
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java
index eb476b4e..72934308 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -31,6 +31,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.Advisor;
+import org.springframework.aop.Pointcut;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.aop.framework.ProxyFactory;
@@ -370,6 +371,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
*/
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
+ Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AutoProxyUtils.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AutoProxyUtils.java
index a771146f..af39672c 100644
--- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AutoProxyUtils.java
+++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AutoProxyUtils.java
@@ -35,7 +35,7 @@ public abstract class AutoProxyUtils {
* to be proxied with its target class (in case of it getting proxied in the first
* place). The value is {@code Boolean.TRUE} or {@code Boolean.FALSE}.
* <p>Proxy factories can set this attribute if they built a target class proxy
- * for a specific bean, and want to enforce that that bean can always be cast
+ * for a specific bean, and want to enforce that bean can always be cast
* to its target class (even if AOP advices get applied through auto-proxying).
* @see #shouldProxyTargetClass
*/
diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java
index b1cdaa0f..28917436 100644
--- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java
+++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java
@@ -235,7 +235,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
if (logger.isInfoEnabled()) {
logger.info("More than one TaskExecutor bean found within the context, and none is named " +
"'taskExecutor'. Mark one of them as primary or name it 'taskExecutor' (possibly " +
- "as an alias) in order to use it for async processing.");
+ "as an alias) in order to use it for async processing: " + ex.getBeanNamesFound());
}
}
}
diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java
index 1ed373ca..4c8273ec 100644
--- a/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java
+++ b/spring-aop/src/main/java/org/springframework/aop/support/AopUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -18,6 +18,7 @@ package org.springframework.aop.support;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.LinkedHashSet;
import java.util.LinkedList;
@@ -34,6 +35,7 @@ import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware;
import org.springframework.core.BridgeMethodResolver;
+import org.springframework.core.MethodIntrospector;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -113,6 +115,30 @@ public abstract class AopUtils {
}
/**
+ * Select an invocable method on the target type: either the given method itself
+ * if actually exposed on the target type, or otherwise a corresponding method
+ * on one of the target type's interfaces or on the target type itself.
+ * @param method the method to check
+ * @param targetType the target type to search methods on (typically an AOP proxy)
+ * @return a corresponding invocable method on the target type
+ * @throws IllegalStateException if the given method is not invocable on the given
+ * target type (typically due to a proxy mismatch)
+ * @since 4.3
+ * @see MethodIntrospector#selectInvocableMethod(Method, Class)
+ */
+ public static Method selectInvocableMethod(Method method, Class<?> targetType) {
+ Method methodToUse = MethodIntrospector.selectInvocableMethod(method, targetType);
+ if (Modifier.isPrivate(methodToUse.getModifiers()) && !Modifier.isStatic(methodToUse.getModifiers()) &&
+ SpringProxy.class.isAssignableFrom(targetType)) {
+ throw new IllegalStateException(String.format(
+ "Need to invoke method '%s' found on proxy for target class '%s' but cannot " +
+ "be delegated to target bean. Switch its visibility to package or protected.",
+ method.getName(), method.getDeclaringClass().getSimpleName()));
+ }
+ return methodToUse;
+ }
+
+ /**
* Determine whether the given method is an "equals" method.
* @see java.lang.Object#equals
*/
@@ -196,6 +222,11 @@ public abstract class AopUtils {
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
+ if (methodMatcher == MethodMatcher.TRUE) {
+ // No need to iterate the methods if we're matching any method anyway...
+ return true;
+ }
+
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
@@ -204,7 +235,7 @@ public abstract class AopUtils {
Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
for (Class<?> clazz : classes) {
- Method[] methods = clazz.getMethods();
+ Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if ((introductionAwareMethodMatcher != null &&
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||