我想用@ Annotation1包装所有注释的方法,但不包括@ Annotation2。
到目前为止,我尝试了3种方法,但都失败了。第一个是切入点表达式。例如:
@Before("@annotation(Annotation1) && !@annotation(Annotation2)")
public void doTheWrapping() {
System.out.println("Wrapped!");
}
无论Annotation2如何,此方法都会包含使用Annotation1注释的所有内容。
第二种方法是手动检测Annotation2,但这似乎也不起作用。
@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(method)始终返回null。它似乎根本不知道该方法的注释。
最后,我尝试使用@Pointcuts。
@Pointcut("execution(@Annotation1 * *(..))")
public void annotatedWithAnnotation1() {}
@Pointcut("execution(@Annotation2 * *(..))")
public void annotatedWithAnnotation2() {}
@Before("annotatedWithAnnotation1() && !annotatedWithAnnotation2()")
public void doTheWrapping() {
System.out.println("Wrapped!");
}
再一次,无论Annotation2如何,都会包装所有内容。
有人可以帮忙吗?
解 事实证明答案真的很简单。将@ Annotation2移动到接口而不是实现解决了这个问题。
答案 0 :(得分:1)
只要方面与两个注释位于同一个包中,您的第一个切入点就应该有效。否则,您需要指定完全限定的类名。这是一个独立的AspectJ示例。在Spring AOP中它应该是相同的:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation1 {}
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation2 {}
package de.scrum_master.app;
public class Application {
@Annotation1
public void foo() {}
@Annotation2
public void bar() {}
@Annotation1
@Annotation2
public void zot() {}
public void baz() {}
public static void main(String[] args) {
Application application = new Application();
application.foo();
application.bar();
application.zot();
application.bar();
}
}
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("@annotation(de.scrum_master.app.Annotation1) && !@annotation(de.scrum_master.app.Annotation2)")
public void doTheWrapping(JoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
}
}
AspectJ的控制台输出:
call(void de.scrum_master.app.Application.foo())
execution(void de.scrum_master.app.Application.foo())
Spring AOP的控制台输出:
由于Spring AOP不支持call()
切入点,因此只要execution()
类Application
为@Component
,就会拦截execution(void de.scrum_master.app.Application.foo())
个连接点:
public abstract class A
{
}
public class B : A
{
public B()
{
Console.WriteLine("I am of type B!");
}
}
public class C : A
{
public C()
{
Console.WriteLine("I am of type C!");
}
}
static List<A> listOfStuff = new List<A>();
public static void doSomething()
{
listOfStuff.Add(new B());
listOfStuff.Add(new C());
foreach (A item in listOfStuff)
{
doOperation(item);
}
}
static void doOperation(A thing1)
{
if (thing1 is B)
{
//Do code for B
}
if (thing1 is C)
{
//Do code for C
}
}