MethodInvocations and ProceedingJoinPoints always expose original method (not bridge); ProceedingJoinPoint resolves parameter names using ASM-based parameter name discovery
This commit is contained in:
parent
02164ab6a7
commit
85bc98ea4b
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,6 +27,7 @@ import org.aspectj.lang.reflect.SourceLocation;
|
||||||
import org.aspectj.runtime.internal.AroundClosure;
|
import org.aspectj.runtime.internal.AroundClosure;
|
||||||
|
|
||||||
import org.springframework.aop.ProxyMethodInvocation;
|
import org.springframework.aop.ProxyMethodInvocation;
|
||||||
|
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +152,9 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||||
/**
|
/**
|
||||||
* Lazily initialized MethodSignature.
|
* Lazily initialized MethodSignature.
|
||||||
*/
|
*/
|
||||||
private class MethodSignatureImpl implements Signature, MethodSignature {
|
private class MethodSignatureImpl implements MethodSignature {
|
||||||
|
|
||||||
|
private volatile String[] parameterNames;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return methodInvocation.getMethod().getName();
|
return methodInvocation.getMethod().getName();
|
||||||
|
@ -182,10 +185,10 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getParameterNames() {
|
public String[] getParameterNames() {
|
||||||
// TODO consider allowing use of ParameterNameDiscoverer, or tying into
|
if (this.parameterNames == null) {
|
||||||
// parameter names exposed for argument binding...
|
this.parameterNames = (new LocalVariableTableParameterNameDiscoverer()).getParameterNames(getMethod());
|
||||||
throw new UnsupportedOperationException(
|
}
|
||||||
"Parameter names cannot be determined unless compiled by AspectJ compiler");
|
return this.parameterNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getExceptionTypes() {
|
public Class[] getExceptionTypes() {
|
||||||
|
@ -204,62 +207,55 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
|
||||||
return toString(false, true, false, true);
|
return toString(false, true, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toString(boolean includeModifier,
|
private String toString(boolean includeModifier, boolean includeReturnTypeAndArgs,
|
||||||
boolean includeReturnTypeAndArgs,
|
boolean useLongReturnAndArgumentTypeName, boolean useLongTypeName) {
|
||||||
boolean useLongReturnAndArgumentTypeName,
|
|
||||||
boolean useLongTypeName) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (includeModifier) {
|
if (includeModifier) {
|
||||||
sb.append(Modifier.toString(getModifiers()));
|
sb.append(Modifier.toString(getModifiers()));
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
if (includeReturnTypeAndArgs) {
|
if (includeReturnTypeAndArgs) {
|
||||||
appendType(sb, getReturnType(),
|
appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
|
||||||
useLongReturnAndArgumentTypeName);
|
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
appendType(sb, getDeclaringType(), useLongTypeName);
|
appendType(sb, getDeclaringType(), useLongTypeName);
|
||||||
sb.append(".");
|
sb.append(".");
|
||||||
sb.append(getMethod().getName());
|
sb.append(getMethod().getName());
|
||||||
sb.append("(");
|
sb.append("(");
|
||||||
|
|
||||||
Class[] parametersTypes = getParameterTypes();
|
Class[] parametersTypes = getParameterTypes();
|
||||||
appendTypes(sb, parametersTypes, includeReturnTypeAndArgs,
|
appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
|
||||||
useLongReturnAndArgumentTypeName);
|
|
||||||
sb.append(")");
|
sb.append(")");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void appendTypes(StringBuilder sb, Class<?>[] types,
|
private void appendTypes(StringBuilder sb, Class<?>[] types,
|
||||||
boolean includeArgs, boolean useLongReturnAndArgumentTypeName) {
|
boolean includeArgs, boolean useLongReturnAndArgumentTypeName) {
|
||||||
if (includeArgs) {
|
if (includeArgs) {
|
||||||
for (int size = types.length, i = 0; i < size; i++) {
|
for (int size = types.length, i = 0; i < size; i++) {
|
||||||
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
|
appendType(sb, types[i], useLongReturnAndArgumentTypeName);
|
||||||
if (i < size - 1) {
|
if (i < size - 1) {
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
else {
|
||||||
if (types.length != 0) {
|
if (types.length != 0) {
|
||||||
sb.append("..");
|
sb.append("..");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendType(StringBuilder sb, Class<?> type, boolean useLongTypeName) {
|
||||||
|
if (type.isArray()) {
|
||||||
|
appendType(sb, type.getComponentType(), useLongTypeName);
|
||||||
|
sb.append("[]");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendType(StringBuilder sb, Class<?> type,
|
|
||||||
boolean useLongTypeName) {
|
|
||||||
if (type.isArray()) {
|
|
||||||
appendType(sb, type.getComponentType(), useLongTypeName);
|
|
||||||
sb.append("[]");
|
|
||||||
} else {
|
|
||||||
if (type.getPackage() != null
|
|
||||||
&& type.getPackage().equals("java.lang")) {
|
|
||||||
useLongTypeName = false;
|
|
||||||
}
|
|
||||||
sb.append(useLongTypeName ? type.getName() : type.getSimpleName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazily initialized SourceLocation.
|
* Lazily initialized SourceLocation.
|
||||||
|
|
|
@ -177,7 +177,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||||
setProxyContext = true;
|
setProxyContext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,
|
// May be null. Get as late as possible to minimize the time we "own" the target,
|
||||||
// in case it comes from a pool.
|
// in case it comes from a pool.
|
||||||
target = targetSource.getTarget();
|
target = targetSource.getTarget();
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
|
@ -255,7 +255,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we get here, aopr2 is the other AopProxy.
|
// If we get here, otherProxy is the other AopProxy.
|
||||||
return AopProxyUtils.equalsInProxy(this.advised, otherProxy.advised);
|
return AopProxyUtils.equalsInProxy(this.advised, otherProxy.advised);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,6 +27,7 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
|
||||||
import org.springframework.aop.ProxyMethodInvocation;
|
import org.springframework.aop.ProxyMethodInvocation;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.core.BridgeMethodResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring's implementation of the AOP Alliance
|
* Spring's implementation of the AOP Alliance
|
||||||
|
@ -107,7 +108,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||||
this.proxy = proxy;
|
this.proxy = proxy;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.targetClass = targetClass;
|
this.targetClass = targetClass;
|
||||||
this.method = method;
|
this.method = BridgeMethodResolver.findBridgedMethod(method);
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
|
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.aop.aspectj;
|
package org.springframework.aop.aspectj;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -28,7 +26,10 @@ import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.aspectj.lang.reflect.SourceLocation;
|
import org.aspectj.lang.reflect.SourceLocation;
|
||||||
import org.aspectj.runtime.reflect.Factory;
|
import org.aspectj.runtime.reflect.Factory;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import test.beans.ITestBean;
|
||||||
|
import test.beans.TestBean;
|
||||||
|
|
||||||
import org.springframework.aop.MethodBeforeAdvice;
|
import org.springframework.aop.MethodBeforeAdvice;
|
||||||
import org.springframework.aop.framework.AopContext;
|
import org.springframework.aop.framework.AopContext;
|
||||||
|
@ -36,9 +37,6 @@ import org.springframework.aop.framework.ProxyFactory;
|
||||||
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
|
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
|
||||||
import test.beans.ITestBean;
|
|
||||||
import test.beans.TestBean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
@ -83,7 +81,7 @@ public final class MethodInvocationProceedingJoinPointTests {
|
||||||
|
|
||||||
public void before(Method method, Object[] args, Object target) throws Throwable {
|
public void before(Method method, Object[] args, Object target) throws Throwable {
|
||||||
JoinPoint jp = AbstractAspectJAdvice.currentJoinPoint();
|
JoinPoint jp = AbstractAspectJAdvice.currentJoinPoint();
|
||||||
assertTrue("Method named in toString", jp.toString().indexOf(method.getName()) != -1);
|
assertTrue("Method named in toString", jp.toString().contains(method.getName()));
|
||||||
// Ensure that these don't cause problems
|
// Ensure that these don't cause problems
|
||||||
jp.toShortString();
|
jp.toShortString();
|
||||||
jp.toLongString();
|
jp.toLongString();
|
||||||
|
@ -108,7 +106,7 @@ public final class MethodInvocationProceedingJoinPointTests {
|
||||||
thisProxy.setAge(newAge);
|
thisProxy.setAge(newAge);
|
||||||
assertEquals(newAge, thisProxy.getAge());
|
assertEquals(newAge, thisProxy.getAge());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSame(AopContext.currentProxy(), thisProxy);
|
assertSame(AopContext.currentProxy(), thisProxy);
|
||||||
assertSame(target, raw);
|
assertSame(target, raw);
|
||||||
|
|
||||||
|
@ -122,13 +120,6 @@ public final class MethodInvocationProceedingJoinPointTests {
|
||||||
assertTrue(Arrays.equals(method.getParameterTypes(), msig.getParameterTypes()));
|
assertTrue(Arrays.equals(method.getParameterTypes(), msig.getParameterTypes()));
|
||||||
assertEquals(method.getReturnType(), msig.getReturnType());
|
assertEquals(method.getReturnType(), msig.getReturnType());
|
||||||
assertTrue(Arrays.equals(method.getExceptionTypes(), msig.getExceptionTypes()));
|
assertTrue(Arrays.equals(method.getExceptionTypes(), msig.getExceptionTypes()));
|
||||||
try {
|
|
||||||
msig.getParameterNames();
|
|
||||||
fail("Can't determine parameter names");
|
|
||||||
}
|
|
||||||
catch (UnsupportedOperationException ex) {
|
|
||||||
// Expected
|
|
||||||
}
|
|
||||||
msig.toLongString();
|
msig.toLongString();
|
||||||
msig.toShortString();
|
msig.toShortString();
|
||||||
}
|
}
|
||||||
|
@ -223,4 +214,5 @@ public final class MethodInvocationProceedingJoinPointTests {
|
||||||
// we don't realy care...
|
// we don't realy care...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue