Browse Source

AOP proxies with annotation-based aspects are serializable now

Issue: SPR-6910
pull/912/merge
Juergen Hoeller 10 years ago
parent
commit
4adb7e2500
  1. 74
      spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java
  2. 8
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java
  3. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java
  4. 20
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java
  5. 8
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java
  6. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java
  7. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java
  8. 43
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java
  9. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java
  10. 55
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java
  11. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java
  12. 11
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java
  13. 6
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java
  14. 7
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java
  15. 16
      spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectJPointcutAdvisorTests.java
  16. 27
      spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java

74
spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java

@ -16,6 +16,9 @@ @@ -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; @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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.

8
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterAdvice.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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 @@ -37,6 +40,7 @@ public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodI
super(aspectJBeforeAdviceMethod, pointcut, aif);
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {

7
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java

@ -16,6 +16,7 @@ @@ -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; @@ -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 @@ -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 @@ -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

20
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterThrowingAdvice.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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 @@ -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 @@ -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 @@ -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());
}
}

8
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAroundAdvice.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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 @@ -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 @@ -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)) {

7
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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 @@ -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);

7
spring-aop/src/main/java/org/springframework/aop/aspectj/SingletonAspectInstanceFactory.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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;

43
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AspectMetadata.java

@ -16,6 +16,10 @@ @@ -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; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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);
}
}

7
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/BeanFactoryAspectInstanceFactory.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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;

55
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/InstantiationModelAwarePointcutAdvisorImpl.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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,26 +40,33 @@ import org.springframework.aop.support.Pointcuts; @@ -37,26 +40,33 @@ 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 Advice instantiatedAdvice;
private final MetadataAwareAspectInstanceFactory aspectInstanceFactory;
private int declarationOrder;
private final int declarationOrder;
private String aspectName;
private final String aspectName;
private final Pointcut pointcut;
private final boolean lazy;
private Advice instantiatedAdvice;
private Boolean isBeforeAdvice;
@ -67,7 +77,10 @@ class InstantiationModelAwarePointcutAdvisorImpl @@ -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 @@ -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 @@ -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 @@ -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 @@ -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.

7
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/LazySingletonAspectInstanceFactoryDecorator.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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;

11
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/PrototypeAspectInstanceFactory.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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

6
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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;

7
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/SingletonMetadataAwareAspectInstanceFactory.java

@ -1,5 +1,5 @@ @@ -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 @@ @@ -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; @@ -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;

16
spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectJPointcutAdvisorTests.java

@ -1,5 +1,5 @@ @@ -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.*; @@ -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 {
@ -53,19 +54,18 @@ public final class AspectJPointcutAdvisorTests { @@ -53,19 +54,18 @@ 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)

27
spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AspectProxyFactoryTests.java

@ -16,13 +16,13 @@ @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -193,11 +206,9 @@ public class AspectProxyFactoryTests {
}
/**
* @author Rod Johnson
*/
@Aspect
class MultiplyReturnValue {
@SuppressWarnings("serial")
class MultiplyReturnValue implements Serializable {
private int multiple = 2;

Loading…
Cancel
Save