summaryrefslogtreecommitdiff
path: root/spring-aop/src
diff options
context:
space:
mode:
Diffstat (limited to 'spring-aop/src')
-rw-r--r--spring-aop/src/main/java/org/aopalliance/aop/Advice.java28
-rw-r--r--spring-aop/src/main/java/org/aopalliance/aop/AspectException.java48
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java59
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java41
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java69
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java37
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java65
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java56
-rw-r--r--spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java41
-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
-rw-r--r--spring-aop/src/main/resources/META-INF/spring.schemas3
-rw-r--r--spring-aop/src/main/resources/org/springframework/aop/config/spring-aop-4.3.xsd409
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java3
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPointTests.java3
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java35
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java7
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java27
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/framework/AopProxyUtilsTests.java15
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/framework/ProxyFactoryTests.java54
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java3
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java3
-rw-r--r--spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java3
48 files changed, 1233 insertions, 98 deletions
diff --git a/spring-aop/src/main/java/org/aopalliance/aop/Advice.java b/spring-aop/src/main/java/org/aopalliance/aop/Advice.java
new file mode 100644
index 00000000..6dcbc4af
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/aop/Advice.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ * 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.aopalliance.aop;
+
+/**
+ * Tag interface for Advice. Implementations can be any type
+ * of advice, such as Interceptors.
+ *
+ * @author Rod Johnson
+ * @version $Id: Advice.java,v 1.1 2004/03/19 17:02:16 johnsonr Exp $
+ */
+public interface Advice {
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/aop/AspectException.java b/spring-aop/src/main/java/org/aopalliance/aop/AspectException.java
new file mode 100644
index 00000000..c634d51a
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/aop/AspectException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ * 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.aopalliance.aop;
+
+/**
+ * Superclass for all AOP infrastructure exceptions.
+ * Unchecked, as such exceptions are fatal and end user
+ * code shouldn't be forced to catch them.
+ *
+ * @author Rod Johnson
+ * @author Bob Lee
+ * @author Juergen Hoeller
+ */
+@SuppressWarnings("serial")
+public class AspectException extends RuntimeException {
+
+ /**
+ * Constructor for AspectException.
+ * @param message the exception message
+ */
+ public AspectException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructor for AspectException.
+ * @param message the exception message
+ * @param cause the root cause, if any
+ */
+ public AspectException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java
new file mode 100644
index 00000000..7e0ac706
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+/**
+ * Intercepts the construction of a new object.
+ *
+ * <p>The user should implement the {@link
+ * #construct(ConstructorInvocation)} method to modify the original
+ * behavior. E.g. the following class implements a singleton
+ * interceptor (allows only one unique instance for the intercepted
+ * class):
+ *
+ * <pre class=code>
+ * class DebuggingInterceptor implements ConstructorInterceptor {
+ * Object instance=null;
+ *
+ * Object construct(ConstructorInvocation i) throws Throwable {
+ * if(instance==null) {
+ * return instance=i.proceed();
+ * } else {
+ * throw new Exception("singleton does not allow multiple instance");
+ * }
+ * }
+ * }
+ * </pre>
+ *
+ * @author Rod Johnson
+ */
+public interface ConstructorInterceptor extends Interceptor {
+
+ /**
+ * Implement this method to perform extra treatments before and
+ * after the construction of a new object. Polite implementations
+ * would certainly like to invoke {@link Joinpoint#proceed()}.
+ * @param invocation the construction joinpoint
+ * @return the newly created object, which is also the result of
+ * the call to {@link Joinpoint#proceed()}; might be replaced by
+ * the interceptor
+ * @throws Throwable if the interceptors or the target object
+ * throws an exception
+ */
+ Object construct(ConstructorInvocation invocation) throws Throwable;
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java
new file mode 100644
index 00000000..a453ac32
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Description of an invocation to a constuctor, given to an
+ * interceptor upon constructor-call.
+ *
+ * <p>A constructor invocation is a joinpoint and can be intercepted
+ * by a constructor interceptor.
+ *
+ * @author Rod Johnson
+ * @see ConstructorInterceptor
+ */
+public interface ConstructorInvocation extends Invocation {
+
+ /**
+ * Get the constructor being called.
+ * <p>This method is a friendly implementation of the
+ * {@link Joinpoint#getStaticPart()} method (same result).
+ * @return the constructor being called
+ */
+ Constructor<?> getConstructor();
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java
new file mode 100644
index 00000000..eef409a7
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+import org.aopalliance.aop.Advice;
+
+/**
+ * This interface represents a generic interceptor.
+ *
+ * <p>A generic interceptor can intercept runtime events that occur
+ * within a base program. Those events are materialized by (reified
+ * in) joinpoints. Runtime joinpoints can be invocations, field
+ * access, exceptions...
+ *
+ * <p>This interface is not used directly. Use the sub-interfaces
+ * to intercept specific events. For instance, the following class
+ * implements some specific interceptors in order to implement a
+ * debugger:
+ *
+ * <pre class=code>
+ * class DebuggingInterceptor implements MethodInterceptor,
+ * ConstructorInterceptor, FieldInterceptor {
+ *
+ * Object invoke(MethodInvocation i) throws Throwable {
+ * debug(i.getMethod(), i.getThis(), i.getArgs());
+ * return i.proceed();
+ * }
+ *
+ * Object construct(ConstructorInvocation i) throws Throwable {
+ * debug(i.getConstructor(), i.getThis(), i.getArgs());
+ * return i.proceed();
+ * }
+ *
+ * Object get(FieldAccess fa) throws Throwable {
+ * debug(fa.getField(), fa.getThis(), null);
+ * return fa.proceed();
+ * }
+ *
+ * Object set(FieldAccess fa) throws Throwable {
+ * debug(fa.getField(), fa.getThis(), fa.getValueToSet());
+ * return fa.proceed();
+ * }
+ *
+ * void debug(AccessibleObject ao, Object this, Object value) {
+ * ...
+ * }
+ * }
+ * </pre>
+ *
+ * @author Rod Johnson
+ * @see Joinpoint
+ */
+public interface Interceptor extends Advice {
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java b/spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java
new file mode 100644
index 00000000..e785afb4
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+/**
+ * This interface represents an invocation in the program.
+ *
+ * <p>An invocation is a joinpoint and can be intercepted by an
+ * interceptor.
+ *
+ * @author Rod Johnson
+ */
+public interface Invocation extends Joinpoint {
+
+ /**
+ * Get the arguments as an array object.
+ * It is possible to change element values within this
+ * array to change the arguments.
+ * @return the argument of the invocation
+ */
+ Object[] getArguments();
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java b/spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java
new file mode 100644
index 00000000..9328f333
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+import java.lang.reflect.AccessibleObject;
+
+/**
+ * This interface represents a generic runtime joinpoint (in the AOP
+ * terminology).
+ *
+ * <p>A runtime joinpoint is an <i>event</i> that occurs on a static
+ * joinpoint (i.e. a location in a the program). For instance, an
+ * invocation is the runtime joinpoint on a method (static joinpoint).
+ * The static part of a given joinpoint can be generically retrieved
+ * using the {@link #getStaticPart()} method.
+ *
+ * <p>In the context of an interception framework, a runtime joinpoint
+ * is then the reification of an access to an accessible object (a
+ * method, a constructor, a field), i.e. the static part of the
+ * joinpoint. It is passed to the interceptors that are installed on
+ * the static joinpoint.
+ *
+ * @author Rod Johnson
+ * @see Interceptor
+ */
+public interface Joinpoint {
+
+ /**
+ * Proceed to the next interceptor in the chain.
+ * <p>The implementation and the semantics of this method depends
+ * on the actual joinpoint type (see the children interfaces).
+ * @return see the children interfaces' proceed definition
+ * @throws Throwable if the joinpoint throws an exception
+ */
+ Object proceed() throws Throwable;
+
+ /**
+ * Return the object that holds the current joinpoint's static part.
+ * <p>For instance, the target object for an invocation.
+ * @return the object (can be null if the accessible object is static)
+ */
+ Object getThis();
+
+ /**
+ * Return the static part of this joinpoint.
+ * <p>The static part is an accessible object on which a chain of
+ * interceptors are installed.
+ */
+ AccessibleObject getStaticPart();
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java
new file mode 100644
index 00000000..c08fd744
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+/**
+ * Intercepts calls on an interface on its way to the target. These
+ * are nested "on top" of the target.
+ *
+ * <p>The user should implement the {@link #invoke(MethodInvocation)}
+ * method to modify the original behavior. E.g. the following class
+ * implements a tracing interceptor (traces all the calls on the
+ * intercepted method(s)):
+ *
+ * <pre class=code>
+ * class TracingInterceptor implements MethodInterceptor {
+ * Object invoke(MethodInvocation i) throws Throwable {
+ * System.out.println("method "+i.getMethod()+" is called on "+
+ * i.getThis()+" with args "+i.getArguments());
+ * Object ret=i.proceed();
+ * System.out.println("method "+i.getMethod()+" returns "+ret);
+ * return ret;
+ * }
+ * }
+ * </pre>
+ *
+ * @author Rod Johnson
+ */
+public interface MethodInterceptor extends Interceptor {
+
+ /**
+ * Implement this method to perform extra treatments before and
+ * after the invocation. Polite implementations would certainly
+ * like to invoke {@link Joinpoint#proceed()}.
+ * @param invocation the method invocation joinpoint
+ * @return the result of the call to {@link Joinpoint#proceed()};
+ * might be intercepted by the interceptor
+ * @throws Throwable if the interceptors or the target object
+ * throws an exception
+ */
+ Object invoke(MethodInvocation invocation) throws Throwable;
+
+}
diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java
new file mode 100644
index 00000000..6314824d
--- /dev/null
+++ b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ * 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.aopalliance.intercept;
+
+import java.lang.reflect.Method;
+
+/**
+ * Description of an invocation to a method, given to an interceptor
+ * upon method-call.
+ *
+ * <p>A method invocation is a joinpoint and can be intercepted by a
+ * method interceptor.
+ *
+ * @author Rod Johnson
+ * @see MethodInterceptor
+ */
+public interface MethodInvocation extends Invocation {
+
+ /**
+ * Get the method being called.
+ * <p>This method is a frienly implementation of the
+ * {@link Joinpoint#getStaticPart()} method (same result).
+ * @return the method being called
+ */
+ Method getMethod();
+
+}
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)) ||
diff --git a/spring-aop/src/main/resources/META-INF/spring.schemas b/spring-aop/src/main/resources/META-INF/spring.schemas
index 6f3dae37..fda92512 100644
--- a/spring-aop/src/main/resources/META-INF/spring.schemas
+++ b/spring-aop/src/main/resources/META-INF/spring.schemas
@@ -6,4 +6,5 @@ http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframewor
http\://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.2.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
-http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
+http\://www.springframework.org/schema/aop/spring-aop-4.3.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
+http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
diff --git a/spring-aop/src/main/resources/org/springframework/aop/config/spring-aop-4.3.xsd b/spring-aop/src/main/resources/org/springframework/aop/config/spring-aop-4.3.xsd
new file mode 100644
index 00000000..4dd43ca6
--- /dev/null
+++ b/spring-aop/src/main/resources/org/springframework/aop/config/spring-aop-4.3.xsd
@@ -0,0 +1,409 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+
+<xsd:schema xmlns="http://www.springframework.org/schema/aop"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:tool="http://www.springframework.org/schema/tool"
+ targetNamespace="http://www.springframework.org/schema/aop"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+ <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-4.3.xsd"/>
+ <xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-4.3.xsd"/>
+
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Defines the configuration elements for the Spring Framework's AOP support.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:element name="config">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A section (compartmentalization) of AOP-specific configuration (including
+ aspects, pointcuts, etc).
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="pointcut" type="pointcutType" minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A named pointcut definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="advisor" type="advisorType" minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation source="java:org.springframework.aop.Advisor"><![CDATA[
+ A named advisor definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="aspect" type="aspectType" minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A named aspect definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Are class-based (CGLIB) proxies to be created? By default, standard
+ Java interface-based proxies are created.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Indicate that the proxy should be exposed by the AOP framework as a
+ ThreadLocal for retrieval via the AopContext class. Off by default,
+ i.e. no guarantees that AopContext access will work.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="aspectj-autoproxy">
+ <xsd:annotation>
+ <xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><![CDATA[
+ Enables the use of the @AspectJ style of Spring AOP.
+
+ See org.springframework.context.annotation.EnableAspectJAutoProxy Javadoc
+ for information on code-based alternatives to this XML element.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Indicates that only @AspectJ beans with names matched by the (regex)
+ pattern will be considered as defining aspects to use for Spring autoproxying.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:sequence>
+ <xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Are class-based (CGLIB) proxies to be created? By default, standard
+ Java interface-based proxies are created.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Indicate that the proxy should be exposed by the AOP framework as a
+ ThreadLocal for retrieval via the AopContext class. Off by default,
+ i.e. no guarantees that AopContext access will work.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="scoped-proxy">
+ <xsd:complexType>
+ <xsd:annotation>
+ <xsd:documentation source="java:org.springframework.aop.scope.ScopedProxyFactoryBean"><![CDATA[
+ Marks a bean definition as being a scoped proxy.
+
+ A bean marked as such will be exposed via a proxy, with the 'real'
+ bean instance being retrieved from some other source (such as a
+ HttpSession) as and when required.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="proxy-target-class" type="xsd:boolean" default="true">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Are class-based (CGLIB) proxies to be created? This is the default; in order to
+ switch to standard Java interface-based proxies, turn this flag to "false".
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:complexType name="aspectType">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="pointcut" type="pointcutType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A named pointcut definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="declare-parents" type="declareParentsType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ Allows this aspect to introduce additional interfaces that the advised
+ object will transparently implement.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="before" type="basicAdviceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A before advice definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="after" type="basicAdviceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ An after advice definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="after-returning" type="afterReturningAdviceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ An after-returning advice definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="after-throwing" type="afterThrowingAdviceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ An after-throwing advice definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ <xsd:element name="around" type="basicAdviceType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ An around advice definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+ </xsd:choice>
+ <xsd:attribute name="id" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The unique identifier for an aspect.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="ref" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the (backing) bean that encapsulates the aspect.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="order" type="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
+ Controls the ordering of the execution of this aspect when multiple
+ advice executes at a specific joinpoint.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="includeType">
+ <xsd:attribute name="name" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation source="java:java.util.regex.Pattern"><![CDATA[
+ The regular expression defining which beans are to be included in the
+ list of @AspectJ beans; beans with names matched by the pattern will
+ be included.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="pointcutType">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports type="org.springframework.aop.Pointcut"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:attribute name="id" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The unique identifier for a pointcut.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="expression" use="required" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The pointcut expression.
+
+ For example : 'execution(* com.xyz.myapp.service.*.*(..))'
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="declareParentsType">
+ <xsd:attribute name="types-matching" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation source="java:org.springframework.aop.aspectj.TypePatternClassFilter"><![CDATA[
+ The AspectJ type expression that defines what types (classes) the
+ introduction is restricted to.
+
+ An example would be 'org.springframework.beans.ITestBean+'.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="implement-interface" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation source="java:java.lang.Class"><![CDATA[
+ The fully qualified name of the interface that will be introduced.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="default-impl" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation source="java:java.lang.Class"><![CDATA[
+ The fully qualified name of the class that will be instantiated to serve
+ as the default implementation of the introduced interface.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="delegate-ref" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to the bean that will serve
+ as the default implementation of the introduced interface.
+ ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref"/>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="basicAdviceType">
+ <xsd:attribute name="pointcut" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The associated pointcut expression.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="pointcut-ref" type="pointcutRefType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of an associated pointcut definition.
+ ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:expected-type type="org.springframework.aop.Pointcut"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="method" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the method that defines the logic of the advice.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="arg-names" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The comma-delimited list of advice method argument (parameter) names
+ that will be matched from pointcut parameters.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:complexType name="afterReturningAdviceType">
+ <xsd:complexContent>
+ <xsd:extension base="basicAdviceType">
+ <xsd:attribute name="returning" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the method parameter to which the return value must
+ be passed.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="afterThrowingAdviceType">
+ <xsd:complexContent>
+ <xsd:extension base="basicAdviceType">
+ <xsd:attribute name="throwing" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ The name of the method parameter to which the thrown exception must
+ be passed.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="advisorType">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports type="org.springframework.aop.Advisor"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:attribute name="id" type="xsd:string"/>
+ <xsd:attribute name="advice-ref" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to an advice bean.
+ ]]></xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:expected-type type="org.aopalliance.aop.Advice"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="pointcut" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A pointcut expression.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="pointcut-ref" type="pointcutRefType">
+ <xsd:annotation>
+ <xsd:documentation><![CDATA[
+ A reference to a pointcut definition.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="order" type="xsd:token">
+ <xsd:annotation>
+ <xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
+ Controls the ordering of the execution of this advice when multiple
+ advice executes at a specific joinpoint.
+ ]]></xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+
+ <xsd:simpleType name="pointcutRefType">
+ <xsd:annotation>
+ <xsd:appinfo>
+ <tool:annotation kind="ref">
+ <tool:expected-type type="org.springframework.aop.Pointcut"/>
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:union memberTypes="xsd:string"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java
index 5167b5d7..3a365963 100644
--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java
@@ -307,7 +307,8 @@ public class AspectJAdviceParameterNameDiscovererTests {
try {
discoverer.getParameterNames(m);
fail("Expecting " + exceptionType.getName() + " with message '" + message + "'");
- } catch (RuntimeException expected) {
+ }
+ catch (RuntimeException expected) {
assertEquals("Expecting exception of type " + exceptionType.getName(),
exceptionType, expected.getClass());
assertEquals("Exception message does not match expected", message, expected.getMessage());
diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPointTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPointTests.java
index c4b1caac..f8c39e7b 100644
--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPointTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPointTests.java
@@ -215,7 +215,8 @@ public final class MethodInvocationProceedingJoinPointTests {
itb.setSpouse(new TestBean());
try {
itb.unreliableFileOperation();
- } catch (IOException ex) {
+ }
+ catch (IOException ex) {
// we don't realy care...
}
}
diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java
index 22ef9db8..8a9d63a4 100644
--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/TrickyAspectJPointcutExpressionTests.java
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ * 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.aop.aspectj;
import java.lang.annotation.Documented;
@@ -97,12 +113,14 @@ public class TrickyAspectJPointcutExpressionTests {
try {
bean.sayHello();
fail("Expected exception");
- } catch (TestException e) {
- assertEquals(message, e.getMessage());
+ }
+ catch (TestException ex) {
+ assertEquals(message, ex.getMessage());
}
assertEquals(1, logAdvice.getCountThrows());
}
+
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
/**
@@ -115,15 +133,16 @@ public class TrickyAspectJPointcutExpressionTests {
}
+
@SuppressWarnings("serial")
public static class TestException extends RuntimeException {
public TestException(String string) {
super(string);
}
-
}
+
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@@ -131,18 +150,23 @@ public class TrickyAspectJPointcutExpressionTests {
public static @interface Log {
}
+
public static interface TestService {
+
public String sayHello();
}
+
@Log
public static class TestServiceImpl implements TestService {
+
@Override
public String sayHello() {
throw new TestException("TestServiceImpl");
}
}
+
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
private int countBefore = 0;
@@ -154,9 +178,9 @@ public class TrickyAspectJPointcutExpressionTests {
countBefore++;
}
- public void afterThrowing(Exception e) throws Throwable {
+ public void afterThrowing(Exception ex) throws Throwable {
countThrows++;
- throw e;
+ throw ex;
}
public int getCountBefore() {
@@ -171,7 +195,6 @@ public class TrickyAspectJPointcutExpressionTests {
countThrows = 0;
countBefore = 0;
}
-
}
}
diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java
index 3f34ff59..554be1ae 100644
--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.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.
@@ -694,6 +694,11 @@ public abstract class AbstractAspectJAdvisorFactoryTests {
}
@Override
+ public Object getAspectCreationMutex() {
+ return this;
+ }
+
+ @Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java
index 4113f169..0c4304c9 100644
--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java
@@ -16,13 +16,13 @@
package org.springframework.aop.aspectj.annotation;
+import java.io.Serializable;
import java.util.Arrays;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
-import org.junit.Ignore;
import org.junit.Test;
import test.aop.PerThisAspect;
@@ -80,7 +80,18 @@ public class AspectProxyFactoryTests {
}
@Test
- @Ignore // InstantiationModelAwarePointcutAdvisorImpl not serializable yet
+ @SuppressWarnings("unchecked")
+ public void testSerializable() throws Exception {
+ AspectJProxyFactory proxyFactory = new AspectJProxyFactory(new TestBean());
+ proxyFactory.addAspect(LoggingAspectOnVarargs.class);
+ ITestBean proxy = proxyFactory.getProxy();
+ assertTrue(proxy.doWithVarargs(MyEnum.A, MyOtherEnum.C));
+ ITestBean tb = (ITestBean) SerializationTestUtils.serializeAndDeserialize(proxy);
+ assertTrue(tb.doWithVarargs(MyEnum.A, MyOtherEnum.C));
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
public void testWithInstance() throws Exception {
MultiplyReturnValue aspect = new MultiplyReturnValue();
int multiple = 3;
@@ -133,7 +144,8 @@ public class AspectProxyFactoryTests {
}
- public static class TestBean implements ITestBean {
+ @SuppressWarnings("serial")
+ public static class TestBean implements ITestBean, Serializable {
private int age;
@@ -171,7 +183,8 @@ public class AspectProxyFactoryTests {
@Aspect
- public static class LoggingAspectOnVarargs {
+ @SuppressWarnings("serial")
+ public static class LoggingAspectOnVarargs implements Serializable {
@Around("execution(* doWithVarargs(*))")
public Object doLog(ProceedingJoinPoint pjp) throws Throwable {
@@ -193,11 +206,9 @@ public class AspectProxyFactoryTests {
}
-/**
- * @author Rod Johnson
- */
@Aspect
-class MultiplyReturnValue {
+@SuppressWarnings("serial")
+class MultiplyReturnValue implements Serializable {
private int multiple = 2;
diff --git a/spring-aop/src/test/java/org/springframework/aop/framework/AopProxyUtilsTests.java b/spring-aop/src/test/java/org/springframework/aop/framework/AopProxyUtilsTests.java
index ad7ad9dc..42b12f66 100644
--- a/spring-aop/src/test/java/org/springframework/aop/framework/AopProxyUtilsTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/framework/AopProxyUtilsTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 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,8 +16,6 @@
package org.springframework.aop.framework;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.List;
@@ -34,7 +32,7 @@ import static org.junit.Assert.*;
* @author Rod Johnson
* @author Chris Beams
*/
-public final class AopProxyUtilsTests {
+public class AopProxyUtilsTests {
@Test
public void testCompleteProxiedInterfacesWorksWithNull() {
@@ -125,15 +123,10 @@ public final class AopProxyUtilsTests {
assertEquals(Comparable.class, userInterfaces[1]);
}
- @Test(expected=IllegalArgumentException.class)
+ @Test(expected = IllegalArgumentException.class)
public void testProxiedUserInterfacesWithNoInterface() {
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[0],
- new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- return null;
- }
- });
+ (proxy1, method, args) -> null);
AopProxyUtils.proxiedUserInterfaces(proxy);
}
diff --git a/spring-aop/src/test/java/org/springframework/aop/framework/ProxyFactoryTests.java b/spring-aop/src/test/java/org/springframework/aop/framework/ProxyFactoryTests.java
index 7b509ba6..b01b9b80 100644
--- a/spring-aop/src/test/java/org/springframework/aop/framework/ProxyFactoryTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/framework/ProxyFactoryTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 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.framework;
+import java.util.ArrayList;
+import java.util.List;
import javax.accessibility.Accessible;
import javax.swing.JFrame;
import javax.swing.RootPaneContainer;
@@ -31,6 +33,8 @@ import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
+import org.springframework.core.annotation.AnnotationAwareOrderComparator;
+import org.springframework.core.annotation.Order;
import org.springframework.tests.TimeStamped;
import org.springframework.tests.aop.advice.CountingBeforeAdvice;
import org.springframework.tests.aop.interceptor.NopInterceptor;
@@ -49,7 +53,7 @@ import static org.junit.Assert.*;
* @author Chris Beams
* @since 14.05.2003
*/
-public final class ProxyFactoryTests {
+public class ProxyFactoryTests {
@Test
public void testIndexOfMethods() {
@@ -337,6 +341,34 @@ public final class ProxyFactoryTests {
assertTrue(proxy instanceof Accessible);
}
+ @Test
+ public void testInterfaceProxiesCanBeOrderedThroughAnnotations() {
+ Object proxy1 = new ProxyFactory(new A()).getProxy();
+ Object proxy2 = new ProxyFactory(new B()).getProxy();
+ List<Object> list = new ArrayList<Object>(2);
+ list.add(proxy1);
+ list.add(proxy2);
+ AnnotationAwareOrderComparator.sort(list);
+ assertSame(proxy2, list.get(0));
+ assertSame(proxy1, list.get(1));
+ }
+
+ @Test
+ public void testTargetClassProxiesCanBeOrderedThroughAnnotations() {
+ ProxyFactory pf1 = new ProxyFactory(new A());
+ pf1.setProxyTargetClass(true);
+ ProxyFactory pf2 = new ProxyFactory(new B());
+ pf2.setProxyTargetClass(true);
+ Object proxy1 = pf1.getProxy();
+ Object proxy2 = pf2.getProxy();
+ List<Object> list = new ArrayList<Object>(2);
+ list.add(proxy1);
+ list.add(proxy2);
+ AnnotationAwareOrderComparator.sort(list);
+ assertSame(proxy2, list.get(0));
+ assertSame(proxy1, list.get(1));
+ }
+
@SuppressWarnings("serial")
private static class TimestampIntroductionInterceptor extends DelegatingIntroductionInterceptor
@@ -361,4 +393,22 @@ public final class ProxyFactoryTests {
}
}
+
+ @Order(2)
+ public static class A implements Runnable {
+
+ @Override
+ public void run() {
+ }
+ }
+
+
+ @Order(1)
+ public static class B implements Runnable{
+
+ @Override
+ public void run() {
+ }
+ }
+
}
diff --git a/spring-aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java b/spring-aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java
index 5096fe88..a8240839 100644
--- a/spring-aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/interceptor/DebugInterceptorTests.java
@@ -61,7 +61,8 @@ public final class DebugInterceptorTests {
try {
interceptor.invoke(methodInvocation);
fail("Must have propagated the IllegalArgumentException.");
- } catch (IllegalArgumentException expected) {
+ }
+ catch (IllegalArgumentException expected) {
}
checkCallCountTotal(interceptor);
diff --git a/spring-aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java b/spring-aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java
index 5bdeb414..3b811b24 100644
--- a/spring-aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/interceptor/SimpleTraceInterceptorTests.java
@@ -60,7 +60,8 @@ public final class SimpleTraceInterceptorTests {
try {
interceptor.invokeUnderTrace(mi, log);
fail("Must have propagated the IllegalArgumentException.");
- } catch (IllegalArgumentException expected) {
+ }
+ catch (IllegalArgumentException expected) {
}
verify(log).trace(anyString());
diff --git a/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java b/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java
index e805401b..a7890cde 100644
--- a/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/target/ThreadLocalTargetSourceTests.java
@@ -154,7 +154,8 @@ public class ThreadLocalTargetSourceTests {
// try second time
try {
source.getTarget();
- } catch(NullPointerException ex) {
+ }
+ catch (NullPointerException ex) {
fail("Should not throw NPE");
}
}