假设你真的使用完整的 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;
}
}
Aspect:
就像用户一样安德烈·帕绍尔开始在他的代码片段中显示,您需要迭代参数和注释数组才能实现过滤技巧。我认为它非常丑陋,并且可能只是为了记录而缓慢(并且我认为这就是您想要做的),但对于它的价值,这是您的解决方案:
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
哒哒! :-)