AOP proxies with annotation-based aspects are serializable now
Issue: SPR-6910
This commit is contained in:
parent
bb0bc3d415
commit
4adb7e2500
|
|
@ -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;
|
||||
|
||||
|
|
@ -135,7 +142,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
|||
*/
|
||||
private int joinPointStaticPartArgumentIndex = -1;
|
||||
|
||||
private Map<String, Integer> argumentBindings = null;
|
||||
private Map<String, Integer> argumentBindings;
|
||||
|
||||
private boolean argumentsIntrospected = false;
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -250,17 +259,17 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
|||
this.argumentNames[i] + "' that is not a valid Java identifier");
|
||||
}
|
||||
}
|
||||
if (argumentNames != null) {
|
||||
if (aspectJAdviceMethod.getParameterTypes().length == argumentNames.length + 1) {
|
||||
if (this.argumentNames != null) {
|
||||
if (this.aspectJAdviceMethod.getParameterTypes().length == this.argumentNames.length + 1) {
|
||||
// May need to add implicit join point arg name...
|
||||
Class<?> firstArgType = aspectJAdviceMethod.getParameterTypes()[0];
|
||||
Class<?> firstArgType = this.aspectJAdviceMethod.getParameterTypes()[0];
|
||||
if (firstArgType == JoinPoint.class ||
|
||||
firstArgType == ProceedingJoinPoint.class ||
|
||||
firstArgType == JoinPoint.StaticPart.class) {
|
||||
String[] oldNames = argumentNames;
|
||||
argumentNames = new String[oldNames.length + 1];
|
||||
argumentNames[0] = "THIS_JOIN_POINT";
|
||||
System.arraycopy(oldNames, 0, argumentNames, 1, oldNames.length);
|
||||
String[] oldNames = this.argumentNames;
|
||||
this.argumentNames = new String[oldNames.length + 1];
|
||||
this.argumentNames[0] = "THIS_JOIN_POINT";
|
||||
System.arraycopy(oldNames, 0, this.argumentNames, 1, oldNames.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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--;
|
||||
|
|
@ -456,13 +465,13 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
|||
|
||||
int numExpectedArgumentNames = this.aspectJAdviceMethod.getParameterTypes().length;
|
||||
if (this.argumentNames.length != numExpectedArgumentNames) {
|
||||
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames
|
||||
+ " arguments to bind by name in advice, but actually found " +
|
||||
throw new IllegalStateException("Expecting to find " + numExpectedArgumentNames +
|
||||
" arguments to bind by name in advice, but actually found " +
|
||||
this.argumentNames.length + " arguments.");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
@ -471,8 +480,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
|||
// specified, and find the discovered argument types.
|
||||
if (this.returningName != null) {
|
||||
if (!this.argumentBindings.containsKey(this.returningName)) {
|
||||
throw new IllegalStateException("Returning argument name '"
|
||||
+ this.returningName + "' was not bound in advice arguments");
|
||||
throw new IllegalStateException("Returning argument name '" + this.returningName +
|
||||
"' was not bound in advice arguments");
|
||||
}
|
||||
else {
|
||||
Integer index = this.argumentBindings.get(this.returningName);
|
||||
|
|
@ -482,8 +491,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
|||
}
|
||||
if (this.throwingName != null) {
|
||||
if (!this.argumentBindings.containsKey(this.throwingName)) {
|
||||
throw new IllegalStateException("Throwing argument name '"
|
||||
+ this.throwingName + "' was not bound in advice arguments");
|
||||
throw new IllegalStateException("Throwing argument name '" + this.throwingName +
|
||||
"' was not bound in advice arguments");
|
||||
}
|
||||
else {
|
||||
Integer index = this.argumentBindings.get(this.throwingName);
|
||||
|
|
@ -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,11 +589,10 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
|
|||
}
|
||||
}
|
||||
|
||||
if (numBound != this.adviceInvocationArgumentCount) {
|
||||
throw new IllegalStateException("Required to bind " + this.adviceInvocationArgumentCount
|
||||
+ " arguments, but only bound " + numBound + " (JoinPointMatch " +
|
||||
(jpMatch == null ? "was NOT" : "WAS") +
|
||||
" bound in invocation)");
|
||||
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)");
|
||||
}
|
||||
|
||||
return adviceInvocationArgs;
|
||||
|
|
@ -665,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.
|
||||
|
|
|
|||
|
|
@ -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,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) {
|
||||
|
|
@ -37,6 +40,7 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodI
|
|||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -40,6 +43,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
|||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
|
|
@ -62,6 +66,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice implement
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Following AspectJ semantics, if a returning clause was specified, then the
|
||||
* advice is only invoked if the returned value is an instance of the given
|
||||
|
|
|
|||
|
|
@ -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,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) {
|
||||
|
|
@ -37,6 +40,7 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
|||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
|
|
@ -57,11 +61,11 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
|||
try {
|
||||
return mi.proceed();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (shouldInvokeOnThrowing(t)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, t);
|
||||
catch (Throwable ex) {
|
||||
if (shouldInvokeOnThrowing(ex)) {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, ex);
|
||||
}
|
||||
throw t;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -69,8 +73,8 @@ public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements
|
|||
* In AspectJ semantics, after throwing advice that specifies a throwing clause
|
||||
* is only invoked if the thrown exception is a subtype of the given throwing type.
|
||||
*/
|
||||
private boolean shouldInvokeOnThrowing(Throwable t) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(t.getClass());
|
||||
private boolean shouldInvokeOnThrowing(Throwable ex) {
|
||||
return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,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) {
|
||||
|
|
@ -41,6 +43,7 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
|||
super(aspectJAroundAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isBeforeAdvice() {
|
||||
return false;
|
||||
|
|
@ -56,7 +59,6 @@ public class AspectJAroundAdvice extends AbstractAspectJAdvice implements Method
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable {
|
||||
if (!(mi instanceof ProxyMethodInvocation)) {
|
||||
|
|
|
|||
|
|
@ -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,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) {
|
||||
|
|
@ -35,6 +37,7 @@ public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements
|
|||
super(aspectJBeforeAdviceMethod, pointcut, aif);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||
invokeAdviceMethod(getJoinPointMatch(), null, null);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,12 +44,27 @@ 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) -
|
||||
* allows us to determine if two pieces of advice come from the
|
||||
* same aspect and hence their relative precedence.
|
||||
*/
|
||||
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
|
||||
|
|
@ -54,13 +73,6 @@ public class AspectMetadata {
|
|||
*/
|
||||
private final Pointcut perClausePointcut;
|
||||
|
||||
/**
|
||||
* The name of this aspect as defined to Spring (the bean name) -
|
||||
* allows us to determine if two pieces of advice come from the
|
||||
* same aspect and hence their relative precedence.
|
||||
*/
|
||||
private String aspectName;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AspectMetadata instance for the given aspect class.
|
||||
|
|
@ -83,10 +95,11 @@ public class AspectMetadata {
|
|||
if (ajType == null) {
|
||||
throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect");
|
||||
}
|
||||
this.ajType = ajType;
|
||||
if (this.ajType.getDeclarePrecedence().length > 0) {
|
||||
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()) {
|
||||
case SINGLETON :
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
|
@ -37,7 +39,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,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,27 +40,34 @@ 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 Pointcut pointcut;
|
||||
private final Class<?> declaringClass;
|
||||
|
||||
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
|
||||
private final String methodName;
|
||||
|
||||
private final Method method;
|
||||
private final Class<?>[] parameterTypes;
|
||||
|
||||
private final boolean lazy;
|
||||
private transient Method aspectJAdviceMethod;
|
||||
|
||||
private final AspectJAdvisorFactory atAspectJAdvisorFactory;
|
||||
|
||||
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
|
||||
|
||||
private final int declarationOrder;
|
||||
|
||||
private final String aspectName;
|
||||
|
||||
private final Pointcut pointcut;
|
||||
|
||||
private final boolean lazy;
|
||||
|
||||
private Advice instantiatedAdvice;
|
||||
|
||||
private int declarationOrder;
|
||||
|
||||
private String aspectName;
|
||||
|
||||
private Boolean isBeforeAdvice;
|
||||
|
||||
private Boolean isAfterAdvice;
|
||||
|
|
@ -67,7 +77,10 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
|||
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
|
||||
|
||||
this.declaredPointcut = ajexp;
|
||||
this.method = method;
|
||||
this.declaringClass = method.getDeclaringClass();
|
||||
this.methodName = method.getName();
|
||||
this.parameterTypes = method.getParameterTypes();
|
||||
this.aspectJAdviceMethod = method;
|
||||
this.atAspectJAdvisorFactory = af;
|
||||
this.aspectInstanceFactory = aif;
|
||||
this.declarationOrder = declarationOrderInAspect;
|
||||
|
|
@ -86,9 +99,9 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
|||
}
|
||||
else {
|
||||
// A singleton aspect.
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
this.pointcut = declaredPointcut;
|
||||
this.pointcut = this.declaredPointcut;
|
||||
this.lazy = false;
|
||||
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,8 +155,8 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
|||
|
||||
|
||||
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
|
||||
return this.atAspectJAdvisorFactory.getAdvice(
|
||||
this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
return this.atAspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
|
||||
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
|
||||
}
|
||||
|
||||
public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() {
|
||||
|
|
@ -191,7 +204,7 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
|||
*/
|
||||
private void determineAdviceType() {
|
||||
AspectJAnnotation<?> aspectJAnnotation =
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method);
|
||||
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.aspectJAdviceMethod);
|
||||
if (aspectJAnnotation == null) {
|
||||
this.isBeforeAdvice = false;
|
||||
this.isAfterAdvice = false;
|
||||
|
|
@ -220,11 +233,21 @@ class InstantiationModelAwarePointcutAdvisorImpl
|
|||
@Override
|
||||
public String toString() {
|
||||
return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() +
|
||||
"]; advice method [" + this.method + "]; perClauseKind=" +
|
||||
"]; advice method [" + this.aspectJAdviceMethod + "]; perClauseKind=" +
|
||||
this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind();
|
||||
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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.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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2007 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,11 +16,13 @@
|
|||
|
||||
package org.springframework.aop.aspectj.annotation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
* AspectInstanceFactory backed by a BeanFactory-provided prototype,
|
||||
* enforcing prototype semantics.
|
||||
* {@link org.springframework.aop.aspectj.AspectInstanceFactory} backed by a
|
||||
* {@link BeanFactory}-provided prototype, enforcing prototype semantics.
|
||||
*
|
||||
* <p>Note that this may instantiate multiple times, which probably won't give the
|
||||
* semantics you expect. Use a {@link LazySingletonAspectInstanceFactoryDecorator}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
|
|
@ -31,9 +31,10 @@ import static org.junit.Assert.*;
|
|||
* @author Rod Johnson
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AspectJPointcutAdvisorTests {
|
||||
public class AspectJPointcutAdvisorTests {
|
||||
|
||||
private final AspectJAdvisorFactory af = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
private AspectJAdvisorFactory af = new ReflectiveAspectJAdvisorFactory();
|
||||
|
||||
@Test
|
||||
public void testSingleton() throws SecurityException, NoSuchMethodException {
|
||||
|
|
@ -41,8 +42,8 @@ public final class AspectJPointcutAdvisorTests {
|
|||
ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS);
|
||||
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(af, ajexp,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new AbstractAspectJAdvisorFactoryTests.ExceptionAspect(null),"someBean"),
|
||||
TestBean.class.getMethod("getAge", (Class[]) null),1,"someBean");
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new AbstractAspectJAdvisorFactoryTests.ExceptionAspect(null), "someBean"),
|
||||
TestBean.class.getMethod("getAge", (Class[]) null), 1, "someBean");
|
||||
assertSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut());
|
||||
assertFalse(ajpa.isPerInstance());
|
||||
}
|
||||
|
|
@ -53,33 +54,32 @@ public final class AspectJPointcutAdvisorTests {
|
|||
ajexp.setExpression(AspectJExpressionPointcutTests.MATCH_ALL_METHODS);
|
||||
|
||||
InstantiationModelAwarePointcutAdvisorImpl ajpa = new InstantiationModelAwarePointcutAdvisorImpl(af, ajexp,
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(),"someBean"), null, 1, "someBean");
|
||||
new SingletonMetadataAwareAspectInstanceFactory(new PerTargetAspect(),"someBean"),
|
||||
TestBean.class.getMethod("getAge", (Class[]) null), 1, "someBean");
|
||||
assertNotSame(Pointcut.TRUE, ajpa.getAspectMetadata().getPerClausePointcut());
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut() instanceof AspectJExpressionPointcut);
|
||||
assertTrue(ajpa.isPerInstance());
|
||||
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getClassFilter().matches(TestBean.class));
|
||||
assertFalse(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(
|
||||
TestBean.class.getMethod("getAge", (Class[]) null),
|
||||
TestBean.class));
|
||||
TestBean.class.getMethod("getAge", (Class[]) null), TestBean.class));
|
||||
|
||||
assertTrue(ajpa.getAspectMetadata().getPerClausePointcut().getMethodMatcher().matches(
|
||||
TestBean.class.getMethod("getSpouse", (Class[]) null),
|
||||
TestBean.class));
|
||||
TestBean.class.getMethod("getSpouse", (Class[]) null), TestBean.class));
|
||||
}
|
||||
|
||||
@Test(expected=AopConfigException.class)
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testPerCflowTarget() {
|
||||
testIllegalInstantiationModel(AbstractAspectJAdvisorFactoryTests.PerCflowAspect.class);
|
||||
}
|
||||
|
||||
@Test(expected=AopConfigException.class)
|
||||
@Test(expected = AopConfigException.class)
|
||||
public void testPerCflowBelowTarget() {
|
||||
testIllegalInstantiationModel(AbstractAspectJAdvisorFactoryTests.PerCflowBelowAspect.class);
|
||||
}
|
||||
|
||||
private void testIllegalInstantiationModel(Class<?> c) throws AopConfigException {
|
||||
new AspectMetadata(c,"someBean");
|
||||
new AspectMetadata(c, "someBean");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue