带注释参数的切入点匹配方法
我需要创建一个具有与方法匹配的切入点的切面,如果:
- 它用 MyAnnotationForMethod 注释
- 它的一个参数(可以有很多)用 @MyAnnotationForParam 注释(但也可以有其他注释)。
方面类看起来像这样
@Pointcut("execution(@MyAnnotationForMethod * *(..,@aspects.MyAnnotationForParam Object, ..)) && args(obj)")
void myPointcut(JoinPoint thisJoinPoint, Object obj) {
}
@Before("myPointcut(thisJoinPoint , obj)")
public void doStuffOnParam(JoinPoint thisJoinPoint, Object obj) {
LOGGER.info("doStuffOnParam :"+obj);
}
带注释的方法
@MyAnnotationForMethod
public string theMethod(String a, @MyAnnotationForParam @OtherAnnotation Object obj, Object b){
LOGGER.info(a+obj+b);
}
With eclipse ->警告:在切入点:
Multiple markers at this line
- no match for this type name: MyAnnotationForMethod [Xlint:invalidAbsoluteTypeName]
- no match for this type name: aspects.MyAnnotationForParam On the before : advice defined in xxx.xxx.xxx.xxx.MyAspect has not been applied [Xlint:adviceDidNotMatch]
使用 http://download.eclipse.org/ 中的最后一个spectJ插件tools/ajdt/35/update
使用maven命令行使用aspectj 1.6.9
[WARNING] no match for this type name: MyAnnotationForMethod [Xlint:invalidAbsoluteTypeName]
[WARNING] no match for this type name: aspects.MyAnnotationForParam [Xlint:invalidAbsoluteTypeName]
[WARNING] advice defined in xxx.xxx.xxx.xxx.MyAspect has not been applied [Xlint:adviceDidNotMatch]
注释:
package com.xxx.xxx.annotation;
// standard imports stripped
@Documented
@Target( { FIELD, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface @MyAnnotationForParam {}
并且
package com.xxx.xxx.annotation;
// standard imports stripped
@Target(METHOD)
@Retention(RUNTIME)
@Documented
public @interface MyAnnotationForMethod {}
当然它不能正常工作。
你能告诉我出了什么问题吗?
谢谢。
I need to create an aspect with a pointcut matching a method if:
- it is annoted with MyAnnotationForMethod
- One of its parameters (can have many) is annotated with @MyAnnotationForParam (but can have other annotations as well).
The aspect class look like this
@Pointcut("execution(@MyAnnotationForMethod * *(..,@aspects.MyAnnotationForParam Object, ..)) && args(obj)")
void myPointcut(JoinPoint thisJoinPoint, Object obj) {
}
@Before("myPointcut(thisJoinPoint , obj)")
public void doStuffOnParam(JoinPoint thisJoinPoint, Object obj) {
LOGGER.info("doStuffOnParam :"+obj);
}
The annoted method
@MyAnnotationForMethod
public string theMethod(String a, @MyAnnotationForParam @OtherAnnotation Object obj, Object b){
LOGGER.info(a+obj+b);
}
With eclipse -> warnings : On the poincut :
Multiple markers at this line
- no match for this type name: MyAnnotationForMethod [Xlint:invalidAbsoluteTypeName]
- no match for this type name: aspects.MyAnnotationForParam On the before : advice defined in xxx.xxx.xxx.xxx.MyAspect has not been applied [Xlint:adviceDidNotMatch]
Using last aspectJ plugin from http://download.eclipse.org/tools/ajdt/35/update
With maven command line using aspectj 1.6.9
[WARNING] no match for this type name: MyAnnotationForMethod [Xlint:invalidAbsoluteTypeName]
[WARNING] no match for this type name: aspects.MyAnnotationForParam [Xlint:invalidAbsoluteTypeName]
[WARNING] advice defined in xxx.xxx.xxx.xxx.MyAspect has not been applied [Xlint:adviceDidNotMatch]
The annotations :
package com.xxx.xxx.annotation;
// standard imports stripped
@Documented
@Target( { FIELD, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface @MyAnnotationForParam {}
and
package com.xxx.xxx.annotation;
// standard imports stripped
@Target(METHOD)
@Retention(RUNTIME)
@Documented
public @interface MyAnnotationForMethod {}
And of course it doesn' work properly.
Can you tell me what is wrong ?
thx.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新:
好的,我能找到的最好的参考是在这个页面上:注释、切入点和建议。
您可以匹配方法,但是您将无法捕获参数(仅捕获方法和注释)。所以你要做的就是结合切入点匹配和反射。像这样的东西:
这是我针对上述方面的测试类:
这是输出:
提示
您可能想要缓存很多这样的内容,不需要在每次执行中解析每个注释的每个参数。保留哪个方法的哪个参数带有注释的映射,并仅处理这些参数。
Updated:
OK, the best reference I could find is on this page: Annotations, Pointcuts and Advice.
You can match the method, however you won't be able to catch the parameter (just the method and the annotation). So what you will have to do is a combination of pointcut matching and reflection. Something like this:
Here is my test class for the above aspect:
and here is the output:
Hint
You will probably want to cache a lot of this, there is no need to parse every parameter of every annotation in every execution. Keep a map of which parameter of which method carries the annotation and process only those parameters.
当从接口实现该方法时,上述解决方案中的 ms.getParameterNames() 调用似乎不起作用。我返回空值。
但是,如果我启用 CGLIB,那么它就可以工作。
The ms.getParameterNames() call in the above solution doesnt seem to work when the method is implemented from an interface. I get back nulls.
However, if I enable CGLIB, then it works.