Spring AOP中如何拦截元注解(带注释的注解)
假设我想找到所有用@Controller注释的类,我会创建这个切入点:
@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controllerPointcut() {}
但是找不到那些用@RestController注释的控制器。 由于 RestController 本身带有 @Controller 注解。
关于如何查找用 @Controller 或 @RestController 注释的类而无需创建两个切入点的任何想法?
=====编辑==== 我这里的真实意图是这样的:
父注解:
public @interface ParentAnnotation {}
子注解(用@ParentAnnotation注解):
@ParentAnnotation
public @interface ChildAnnotation {}
类A:
@ParentAnnotation
public class MyClassA {}
类B:
@ChildAnnotation
public class MyClassB {}
现在我想通过@ParentAnnotation找到MyClassA和MyClassB。 找到MyClassA是没有问题的,但是MyClassB是用@ParentAnnotation间接注释的,有没有通用的方法来处理这种情况?
Suppose I want to find all classes annotated with @Controller, I would create this pointcut:
@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controllerPointcut() {}
But those controllers annotated with @RestController can not be found.
Since RestController itself is annoatated with @Controller.
Any idea on how to find classes annotated either with @Controller or @RestController without having to create two Pointcuts ?
===== edit ====
My real intention here is as follows:
parent annotation:
public @interface ParentAnnotation {}
child annotation (annotated with @ParentAnnotation):
@ParentAnnotation
public @interface ChildAnnotation {}
class A:
@ParentAnnotation
public class MyClassA {}
class B:
@ChildAnnotation
public class MyClassB {}
Now I want to find both MyClassA and MyClassB through @ParentAnnotation.
There's no question for finding MyClassA, but MyClassB is indirectly annotated with @ParentAnnotation, is there a generic way to deal such situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个怎么样?
或者有点短,但如果 Springs 的包中还有其他名称匹配的类(我没有检查),则可能太模糊:
更新: 至于你真正的问题,在你编辑后我现在明白了。这也是可能的,但在语法上有点棘手。让我将您的注释重命名为
MetaAnnotation
和MyAnnotation
,好吗?因为它们并不是真正的彼此的父子,所以在 OOP 意义上不涉及继承,只是嵌套。注释:
请确保注释确实具有运行时范围。我在你的代码中没有看到这一点。
Java 示例类:
一个类使用元注释进行注释,一个类使用带注释的注释,一个没有注释(负面测试用例):
驱动程序应用程序:
因为我正在使用没有 Spring 的纯 Java + AspectJ,我使用这个小应用程序来演示结果。
方面:
控制台日志:
现在,如果您想添加另一级嵌套,请添加一个新注释并用它注释以前未注释的类:
然后将切入点扩展一个更多级别的嵌套/递归:
控制台日志更改为:
PS:只有在 AspectJ 中才需要
execution(* *(..))
部分,以便限制切入点匹配到方法执行,因为AspectJ 比 Spring AOP 可以拦截更多的事件。因此,在 Spring AOP 中,您可以消除该部分以及周围的大括号... || ... || ...
部分。How about this?
Or a little shorter, but maybe too fuzzy if there are other classes with matching names in Springs' packages (I have not checked):
Update: As for your real question, I understand it now after your edit. This is also possible, but kind of tricky syntactically. Let me rename your annotations into
MetaAnnotation
andMyAnnotation
, okay? Because they are not really parent and child of each other, there is no inheritance involved in the the OOP sense, just nesting.Annotations:
Please make sure that the annotations have indeed runtime scope. I did not see that in your code.
Java sample classes:
One class is annotated with the meta annotation, one with the annotated annotation and one with no annotation (negative test case):
Driver application:
Because I am using pure Java + AspectJ without Spring, I am using this little application in order to demonstrate the result.
Aspect:
Console log:
Now if you want to add yet another level of nesting, add a new annotation and annotate the formerly unannotated class with it:
Then extend the pointcut by one more level of nesting/recursion:
The console log changes to:
P.S.: The
execution(* *(..))
part is only necessary in AspectJ in order to limit pointcut matching to method executions because AspectJ can intercept more events than Spring AOP. So in Spring AOP you can eliminate that part and the braces surrounding the... || ... || ...
part.