I am fiddling around with AspectJ and came up with an idea that I don't seem to be able to implement properly (story of my life).
I have defined an aspect :
package my.package;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.ProceedingJoinPoint;
@Aspect
public class MyAspect {
@Pointcut("execution(* *(..)) && this(o)")
public void instanceMethod(Object o) {}
@Pointcut("within(@Marker *)")
public void methodsFromMarkedClasses() {}
@Around("methodsFromMarkedClasses() && instanceMethod(o)")
public Object markedMethodsAdvice(ProceedingJoinPoint joinPoint, Object o) throws Throwable {
// do awesome stuff
return null; //<- not the actual return, just added this so that my head wouldn't hurt
}
}
I have defined @Marker
annotation which is just empty.
The idea is to have the advice markedMethodsAdvice
execute ANY time a method is called on an object of a class marked with @Marker
. Even (and here're the tricky parts) :
Case 1
If said method is inherited from a class that is not marked see example :
Given
package my.package;
public class Alpha {
public void methodA() {}
}
When
package my.package;
@Marked
public class Beta extends Alpha {}
Then
/* Should trigger the advice */
new Beta().methodA();
Case 2
If said method is called on an object of a subclass (Liskov)
Given
@Marked
public class Beta extends Alpha { //still extends A just to be coherent with previous example
public void methodB() {}
}
When
package my.package;
public class Gamma extends Beta {
}
Then
/* Should trigger the advice */
new Gamma().methodB();
(And since I'm greedy I ask this bonus one)
Case 3
If said method is declared on a subclass
Given
@Marked
public class Beta extends Alpha {} //still extends A just to be coherent with previous example
When
package my.package;
public class Gamma extends Beta {
public void methodC() {}
}
Then
/* Should trigger the advice */
new Gamma().methodC();
The aspectj documentation seems to state that this is possible
execution(public void Middle.*())
picks out all method executions for public methods returning void and having no arguments that are either declared in, or inherited by, Middle, even if those methods are overridden in a subclass of Middle
So what did I do wrong ?
You could try to annotate @Marker annotation with @Inherited annotation. Subclasses should inherit @Marker annotation.
java.lang.annotation.Inherited
@Inherited
public @interface Marked{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With