Java AspectJ-尝试包装使用一个注释而不是另一个注释注释的方法

Java AspectJ-尝试包装使用一个注释而不是另一个注释注释的方法,java,spring,aop,aspectj,spring-aop,Java,Spring,Aop,Aspectj,Spring Aop,我想用@Annotation1而不是@Annotation2来包装所有带注释的方法 到目前为止,我已经尝试了3种方法,但都失败了。第一种是使用切入点表达式。例如: @Before("@annotation(Annotation1) && !@annotation(Annotation2)") public void doTheWrapping() { System.out.println("Wrapped!"); } 这种方法将使用Annotation1对所有注释进行包

我想用@Annotation1而不是@Annotation2来包装所有带注释的方法

到目前为止,我已经尝试了3种方法,但都失败了。第一种是使用切入点表达式。例如:

@Before("@annotation(Annotation1) && !@annotation(Annotation2)")
public void doTheWrapping() {
    System.out.println("Wrapped!");
}
这种方法将使用Annotation1对所有注释进行包装,而不考虑Annotation2

第二种方法是手动检测注释2,但这似乎也不起作用

@Before("@annotation(Annotation1)")
public void doTheWrapping(final JoinPoint joinPoint) {
    Method method = MethodSignature.class.cast(joinPoint.getSignature()).getMethod();

    if (AnnotationUtils.getAnnotation(method, Annotation2.class) == null) {
        System.out.println("Wrapped!");
    }
}
此操作失败,因为AnnotationUtils.getAnnotations(方法)始终返回null。它似乎根本不知道方法上的注释

最后,我尝试使用@Pointcuts

@Pointcut("execution(@Annotation1 * *(..))")
public void annotatedWithAnnotation1() {}

@Pointcut("execution(@Annotation2 * *(..))")
public void annotatedWithAnnotation2() {}

@Before("annotatedWithAnnotation1() && !annotatedWithAnnotation2()")
public void doTheWrapping() {
    System.out.println("Wrapped!");
}
同样,不管注释如何,都只需包装所有内容2

有人能帮忙吗

解决方案
结果证明答案非常简单。将@Annotation2移动到接口而不是实现解决了这一问题

只要方面与两个注释在同一个包中,第一个切入点就应该可以工作。否则,您需要指定完全限定的类名。下面是一个独立的AspectJ示例。在Spring AOP中应该是相同的:

package de.scrum\u master.app;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
@保留(RetentionPolicy.RUNTIME)
public@interface Annotation1{}
package de.scrum\u master.app;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
@保留(RetentionPolicy.RUNTIME)
public@interface Annotation2{}
package de.scrum\u master.app;
公共类应用程序{
@注释1
公共void foo(){}
@注释2
公共无效条(){}
@注释1
@注释2
公共void zot(){}
公共void baz(){}
公共静态void main(字符串[]args){
应用程序=新应用程序();
application.foo();
application.bar();
application.zot();
application.bar();
}
}
package de.scrum\u master.aspect;
导入org.aspectj.lang.JoinPoint;
导入org.aspectj.lang.annotation.Aspect;
导入org.aspectj.lang.annotation.Before;
@面貌
公共类MyAspect{
@在(@annotation(de.scrum\u master.app.Annotation1)和&!@annotation(de.scrum\u master.app.Annotation2)之前)
公共void dotherapping(JoinPoint thisJoinPoint){
System.out.println(此连接点);
}
}
AspectJ的控制台输出:

调用(void de.scrum\u master.app.Application.foo()) 执行(void de.scrum\u master.app.Application.foo()) Spring AOP的控制台输出:

因为Spring AOP不支持
call()
切入点,所以只要类
应用程序
是Spring
@组件,就只会拦截
执行()
连接点:

执行(void de.scrum\u master.app.Application.foo())

你能发布一个完整且可复制的例子吗?你的第二个例子对我来说很好。@SotiriosDelimanolis,这很有趣。我怀疑这可能是因为我针对的带注释的方法在Spring服务中,而注释在实现中?我真的不知道,但可能是我得到的签名来自声明,而不是实现。。。只是一个猜测。你最好的选择是提供MCVE。MCVE?这就是完整的例子吗?我会的。。。今天才有最后期限。当我有一分钟的时间,但会有一两天的时间,我会举一个例子。至于对spring的怀疑,我把注释移到了声明中,但没有什么区别。。。这就是理论。