Given this annotation:
package de.scrum_master.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
Let us assume we have three classes:
- a parent class without annotation,
- a plain child class without annotation and
- an annotated child class:
package de.scrum_master.app;
public class Parent {
public void doSomething() {}
}
package de.scrum_master.app;
public class PlainChild extends Parent {
int doSomethingElse() { return 11; }
}
package de.scrum_master.app;
@MyAnnotation
public class AnnotatedChild extends Parent {
String doSomethingSpecial(int number) { return ""; }
}
Here is a little driver application instantiating all three classes, calling all available methods on them, inherited or not, with different signatures and return types:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new Parent().doSomething();
new PlainChild().doSomething();
new PlainChild().doSomethingElse();
new AnnotatedChild().doSomething();
new AnnotatedChild().doSomethingSpecial(123);
}
}
Finally, here is the aspect doing what was asked in the question: It intercepts all method executions in Parent
or any of its subclasses (thus the +
), but only if the class of the current instance this
bears @MyAnnotation
:
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@Around(
"execution(* de.scrum_master.app.Parent+.*(..)) && " +
"@this(de.scrum_master.app.MyAnnotation)"
)
public Object myAdvice(ProceedingJoinPoint thisJoinPoint) {
System.out.println(thisJoinPoint);
System.out.println(" " + thisJoinPoint.getThis());
return thisJoinPoint.proceed();
}
}
The console log:
execution(void de.scrum_master.app.Parent.doSomething())
de.scrum_master.app.AnnotatedChild@681a9515
execution(String de.scrum_master.app.AnnotatedChild.doSomethingSpecial(int))
de.scrum_master.app.AnnotatedChild@13221655
As you can see, doSomething()
is called three times, but only intercepted once. You can also see from the printed getThis()
object, that really the right execution is intercepted.