Search code examples
javaaspectj

How to get the enclosing type with aspectj


please consider this :

public class A
{
  private B bMemeber;
  private Properties myProperties;
}

and

public class B { 
 private Object field;
 public void setField(Object o){...}
}

I have an aspect

    @After("execution(* B.setField(..)) &&! within(PropertiesAspect)")
    public void afterSetField(JoinPoint jp)
    {....}

my question is : is it possible to get the enclosing type of Busing aspectj in my afterSetField as I need to test on some properties contained in the A object


Solution

  • What you want is not easily possible because it is not what AOP was made for. An instance of class B has no idea about whether it is assigned to a member of any other class or is part of any collection or array. The JVM garbage collector does reference counting for internal purposes (freeing memory after an object is no longer referenced), but this is nothing you have access to from an aspect. What you can do with AspectJ is

    • intercept whenever a value or object is assigned to a member variable (set()) pointcut) or when that member is read (get() pointcut). By the way, these pointcuts do not work for local variables, only for members. But when a method is called upon any object that happens to be assigned to a member variable, technically that variable's value does not change, it is still the same (mutable) object, i.e. a method call or an internal state change in a referenced object does not trigger set() in the referencing object, only in the referenced object itself.
    • intercept method calls or executions, which you already do.

    I am not sure that what you want makes any practical sense, but what you can do with some overhead is manual reference bookkeeping like this:

    • Whenever an object of interest is assigned to a member variable, intercept it via set() pointcut and remember it by putting it into a collection maintained by the aspect.
    • By the way, at the same time you also have to remove the old member object from the collection if (and only if!) it is no longer referenced.
    • In your execution() pointcut, find out if the object in question is in the internal collection, retrieve the info about the owning object(s) from the collection and do with it whatever you like.