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.
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.