假设你真的使用完整的 AspectJ 而不是 Spring AOP像许多其他人一样,你应该意识到在完整的 AspectJ 中@annotation(XY)
可能不仅匹配execution()
连接点而且还匹配call()
,即你的建议将被触发两次。更糟糕的是,如果除了方法执行之外的其他地方也被注释了——例如类、字段、构造函数、参数——切入点也将匹配,并且您尝试强制转换MethodSignature
将导致异常。
此外,请注意,在@AspectJ 语法中,您需要提供要匹配的注解的完全限定类名,即不要忘记在包名前面也加上。否则根本就没有对手。因此,在做任何其他事情之前,您要将切入点更改为:
@annotation(de.scrum_master.app.MyAnnotation) && execution(* *(..))
现在这是一个完全自洽的示例,一个SSCCE产生可重复的结果,正如我在您的问题下的评论中所要求的:
注解:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
驱动应用:
如您所见,测试方法具有带有不同类型注释的参数:
- 只有 javax 注释
- javax + 自己的注解
- 只有你自己的注释
- 无注释
我们想忽略#1/2,只打印#3/4。
package de.scrum_master.app;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
public class Application {
public static void main(String[] args) {
new Application().update("foo", 11, "bar", 22);
}
@MyAnnotation
public Response update(
@PathParam("pathParam") String p1,
@PathParam("pathParam2") @MyAnnotation int p2,
@MyAnnotation String text,
int number
) {
return null;
}
}
方面:
正如用户Andre Paschoal开始在他的代码片段中展示的那样,您需要遍历参数和注释数组以完成过滤技巧。我认为这很丑陋,并且可能只是为了记录而很慢(我认为这是你想要做的),但为了它的价值,这是你的解决方案:
package de.scrum_master.aspect;
import java.lang.annotation.Annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
@Aspect
public class ParameterFilterAspect {
@Before("@annotation(de.scrum_master.app.MyAnnotation) && execution(* *(..))")
public void doSomething(JoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Annotation[][] annotationMatrix = methodSignature.getMethod().getParameterAnnotations();
for (int i = 0; i < args.length; i++) {
boolean hasJavaxAnnotation = false;
for (Annotation annotation : annotationMatrix[i]) {
if (annotation.annotationType().getPackage().getName().startsWith("javax.")) {
hasJavaxAnnotation = true;
break;
}
}
if (!hasJavaxAnnotation)
System.out.println(args[i]);
}
}
}
控制台日志:
bar
22
多多!:-)