您不能通过
args()AspectJ
中的任意位置绑定参数,因为这可能导致歧义。试想一下,您有两个或多个相同类型的参数(在这种情况下,使用相同的注释类型进行了注释)。应将其中哪一个绑定到命名
args()参数?所以当
execution(public * *(.., @Deprecated (*), ..))
可以作为独立的表达式(请注意星号的括号),不能与组合使用
args()。因此,如果您不仅要拦截方法本身的执行,而且要查找具有给定批注的第一个或所有参数,则只需执行我在另一篇文章中所介绍的即可。我有点重复自己,但是为了不再次删除答案是这样的:
import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface Constraint {}import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;public class Application { public void method1(@Constraint int i) {} public void method2(String id, @Constraint float f) {} public void method3(int i, @Constraint List<String> strings, @Constraint String s) {} public void method4(int i, @Constraint Set<Integer> numbers, float f, boolean b) {} public void method5(boolean b, String s, @Constraint String s2, float f, int i) {} public void notIntercepted(boolean b, String s, String s2, float f, int i) {} public static void main(String[] args) { List<String> strings = new ArrayList<String>(); strings.add("foo"); strings.add("bar"); Set<Integer> numbers = new HashSet<Integer>(); numbers.add(11); numbers.add(22); numbers.add(33); Application app = new Application(); app.method1(1); app.method2("foo", 1f); app.method3(1, strings, "foo"); app.method4(1, numbers, 1f, true); app.method5(false, "foo", "bar", 1f, 1); app.notIntercepted(false, "foo", "bar", 1f, 1); }}import java.lang.annotation.Annotation;import org.aspectj.lang.SoftException;import org.aspectj.lang.reflect.MethodSignature;public aspect ArgCatcherAspect { before() : execution(public * *(.., @Constraint (*), ..)) { System.out.println(thisJoinPointStaticPart); MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature(); String methodName = signature.getMethod().getName(); Class<?>[] parameterTypes = signature.getMethod().getParameterTypes(); Annotation[][] annotations; try { annotations = thisJoinPoint.getTarget().getClass(). getMethod(methodName, parameterTypes).getParameterAnnotations(); } catch (Exception e) { throw new SoftException(e); } int i = 0; for (Object arg : thisJoinPoint.getArgs()) { for (Annotation annotation : annotations[i]) { if (annotation.annotationType() == Constraint.class) System.out.println(" " + annotation + " -> " + arg); } i++; } }}如您所见,获取给定参数的注释不仅是声明的类型,还有些棘手,但是基本上它的工作方式与我之前的文章相同,即遍历参数列表。



