Я возился с AspectJ и придумал идею, что я, похоже, не умею правильно реализовывать (рассказ о моей жизни).
Я определил аспект:
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
}
}
Я определил аннотацию @Marker
, которая просто пуста.
Идея состоит в том, чтобы дать совет markedMethodsAdvice
выполнить ЛЮБОЕ время, когда вызывается метод для объекта класса, помеченного @Marker
. Даже (и здесь сложные штуки):
Случай 1
Если указанный метод наследуется от класса, который не отмечен, см. пример:
Учитывая
package my.package;
public class Alpha {
public void methodA() {}
}
Когда
package my.package;
@Marked
public class Beta extends Alpha {}
Тогда
/* Should trigger the advice */
new Beta().methodA();
Случай 2
Если указанный метод вызывается в объекте подкласса (Liskov)
Учитывая
@Marked
public class Beta extends Alpha { //still extends A just to be coherent with previous example
public void methodB() {}
}
Когда
package my.package;
public class Gamma extends Beta {
}
Тогда
/* Should trigger the advice */
new Gamma().methodB();
(И так как я жадный, я прошу этот бонус один)
Случай 3
Если указанный метод объявлен в подклассе
Учитывая
@Marked
public class Beta extends Alpha {} //still extends A just to be coherent with previous example
Когда
package my.package;
public class Gamma extends Beta {
public void methodC() {}
}
Тогда
/* Should trigger the advice */
new Gamma().methodC();
Документация aspectj указывает, что это возможно
execution(public void Middle.*())
выбирает все методы исполнения для общедоступных методов, возвращающих void и не имеющих аргументов, которые либо объявлены, либо унаследованы, Middle, даже если эти методы переопределены в подклассе Middle
Так что же я сделал не так?