5

I'm looking for a pointcut that matches method executions in classes that subclass a class with a specific annotation. The excellent AspectJ cheat sheet helped me to create the following pointcut:

within(@my.own.annotations.AnnotationToMatch *) && execution(* *(..))

This matches all method calls of a class A that carries the @AnnotationToMatch, but not method of a class B that extends A. How can I match both?

Dr. Hans-Peter Störr
  • 25,298
  • 30
  • 102
  • 139

2 Answers2

3
public aspect AnnotatedParentPointcutAspect {   

//introducing empty marker interface
declare parents : (@MyAnnotation *) implements TrackedParentMarker;

public pointcut p1() : execution(* TrackedParentMarker+.*(..));

before(): p1(){
    System.out.println("Crosscutted method: "
            +thisJoinPointStaticPart.getSignature().getDeclaringTypeName()
            +"." 
            +thisJoinPointStaticPart.getSignature().getName());
}
}
alehro
  • 2,198
  • 2
  • 25
  • 41
  • 1
    Thanks! For the benefit of others: if you use the annotation style, the declare parents translates to @DeclareParents("(@MyAnnotation *)") private TrackedParentMarker emptyMixinForClassesWithMyAnnotation; – Dr. Hans-Peter Störr Aug 24 '11 at 15:07
  • That works well for super-classes, but not so well for interfaces. I.e. in code such as `MyInterface o = new MyClass()` it looks loke `MyClass` gets loaded before the interface and the condition doesn't match. Adding a `println(MyInterface.class)` before the statement fixes the problem, but is not feasible requirement for library aspects. Any ideas? – ddimitrov Jul 26 '16 at 23:39
3

Another and simpler possibility is to declare the annotation as @Inherited - thus it applies to the subclasses as well.

Dr. Hans-Peter Störr
  • 25,298
  • 30
  • 102
  • 139
  • But it won't work if you cannot declare annotation as @Inherited. E.g. base classes from third party libraries. – alehro Aug 24 '11 at 21:00