Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Limiting runtime type of target/this objects in pointcut

Hi Andy, hi community!

There is no easy way to specify a pointcut like "match all getters of base class and all subclasses, but exclude instances of the base class". I mean something like this (found similarly in a StackOverflow question):

------------------------------------------------------------------------

package de.scrum_master.app;

public class Base {
  private int id = 11;

  public int getId() {
    return id;
  }
}

------------------------------------------------------------------------

package de.scrum_master.app;

public class Sub extends Base {
  private String name = "John Doe";

  public String getName() {
    return name;
  }

  public static void main(String[] args) {
    new Base().getId();
    new Sub().getId();
    new Sub().getName();
  }
}

------------------------------------------------------------------------

package de.scrum_master.aspect;

import de.scrum_master.app.Base;

public aspect MyAspect {
  before(Base base) : execution(* Base+.get*()) && this(base) {
    if (base.getClass().equals(Base.class))
      return;
    System.out.println(thisJoinPoint);
    System.out.println("  " + thisJoinPoint.getTarget());
  }
}

------------------------------------------------------------------------

Console log:

execution(int de.scrum_master.app.Base.getId())
  de.scrum_master.app.Sub@6500df86
execution(String de.scrum_master.app.Sub.getName())
  de.scrum_master.app.Sub@402a079c

------------------------------------------------------------------------

I cannot use something like

  target(Base+) && !target(Base)

because if this is of course mutually exclusive and a pointcut like that would never match anything. This imaginary syntax

  target(!Base && Base++)

also does not work because this/target need exact type names, not patterns. So there does not seem to be a way around something like binding this/target and

    if (base.getClass().equals(Base.class)) return;

Okay, I could factor the check out into an if() pointcut, but that is just syntactic sugar and not applicable to Spring AOP, only to AspectJ.

The workaround to manually annotate either the base class or all subclasses and in-/exclude based on such annotations is also not nice and not easily feasible via ITD. The only way to pull this off would be to use AspectJ's annotation processing feature, which again would not work in Spring AOP and would also be a major obstacle for unexperienced AspectJ users.

Have I overlooked anything? If so, what? If not, do you think this kind of feature would be a helpful addition to the AspectJ pointcut syntax?

Regards
-- 
Alexander Kriegisch
https://scrum-master.de


Back to the top