这个怎么样?
@Pointcut(
"within(@org.springframework.stereotype.Controller *) || " +
"within(@org.springframework.web.bind.annotation.RestController *)" +
)
或者稍微短一点,但如果Springs的包中有其他具有匹配名称的类,则可能太模糊了(我没有检查):
@Pointcut("within(@(org.springframework..*Controller) *)")
更新:
至于你真正的问题,经过你的编辑,我现在明白了。这也是可能的,但在句法上有点棘手。让我将您的批注重命名为
MetaAnnotation
和
MyAnnotation
可以因为它们实际上不是彼此的父级和子级,所以OOP意义上不涉及继承,只涉及嵌套。
注释:
请确保注释确实具有运行时范围。我在你的代码中没有看到这一点。
package de.scrum_master.app;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ TYPE })
public @interface MetaAnnotation {}
package de.scrum_master.app;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ TYPE })
@MetaAnnotation
public @interface MyAnnotation {}
Java示例类:
一个类带有元注释,一个带有注释,一个没有注释(否定测试用例):
package de.scrum_master.app;
@MetaAnnotation
public class MyClassA {
public void doSomething() {}
}
package de.scrum_master.app;
@MyAnnotation
public class MyClassB {
public void doSomething() {}
}
package de.scrum_master.app;
public class MyClassC {
public void doSomething() {}
}
驱动程序应用程序:
因为我使用的是没有Spring的纯Java+AspectJ,所以我使用这个小应用程序来演示结果。
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new MyClassA().doSomething();
new MyClassB().doSomething();
new MyClassC().doSomething();
}
}
方面:
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 MetaAnnotationInterceptor {
@Before(
"execution(* *(..)) && (" +
"within(@de.scrum_master.app.MetaAnnotation *) || " +
"within(@(@de.scrum_master.app.MetaAnnotation *) *)" +
")"
)
public void myAdvice(JoinPoint thisJoinPoint){
System.out.println(thisJoinPoint);
}
}
控制台日志:
execution(void de.scrum_master.app.MyClassA.doSomething())
execution(void de.scrum_master.app.MyClassB.doSomething())
现在,如果要添加另一层嵌套,请添加一个新注释,并用它注释以前未注释的类:
package de.scrum_master.app;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ TYPE })
@MyAnnotation
public @interface MyOtherAnnotation {}
package de.scrum_master.app;
@MyOtherAnnotation
public class MyClassC {
public void doSomething() {}
}
然后将切入点扩展一个以上的嵌套/递归级别:
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 MetaAnnotationInterceptor {
@Before(
"execution(* *(..)) && (" +
"within(@de.scrum_master.app.MetaAnnotation *) || " +
"within(@(@de.scrum_master.app.MetaAnnotation *) *) || " +
"within(@(@(@de.scrum_master.app.MetaAnnotation *) *) *)" +
")"
)
public void myAdvice(JoinPoint thisJoinPoint){
System.out.println(thisJoinPoint);
}
}
控制台日志更改为:
execution(void de.scrum_master.app.MyClassA.doSomething())
execution(void de.scrum_master.app.MyClassB.doSomething())
execution(void de.scrum_master.app.MyClassC.doSomething())
P、 S.:The
execution(* *(..))
part仅在AspectJ中是必需的,以便将切入点匹配限制为方法执行,因为AspectJ可以截获比Spring AOP更多的事件。因此,在Spring AOP中,可以消除该部分和
... || ... || ...
部分