Pointcut для соответствия всем вызовам общедоступных методов, кроме вызовов self

Я пытаюсь написать аспект, который отслеживает вызовы общедоступных методов для различных объектов, но игнорирует обращения к себе. Для этого у меня есть такой аспект:

abstract aspect MonitorPublicMethodCalls {

  abstract pointcut matchingType();
  pointcut matchingCall(): call(public * *(..));
  pointcut notSelf();

  Object around(Object t): matchingType() && matchingCall()  && notSelf() {
    // do something useful with the call
    if(/* allow call? */) {
      return proceed();
    } else {
      throw new IllegalStateException("Badness!");
    }
  }
}

Это будет отслеживать все вызовы всех общедоступных методов, но чтобы игнорировать вызовы себе, я бы действительно хотел определить notSelf как что-то вроде

pointcut notSelf(Object o): target(o) && !this(o)

Однако при этом я получаю сообщение об ошибке: «отрицание не допускает привязки» при отрицании this(o). Прямо сейчас в качестве обходного пути я проверяю в теле совета, совпадает ли цель с этой, и если да, то обхожу другую логику, однако это означает, что аспект вплетен в большее количество мест, чем это действительно необходимо. Можно ли определить ограничение, чтобы избежать обращений к себе?


person iainmcgin    schedule 24.03.2011    source источник


Ответы (1)


Попробуй это:

pointcut selfAndTarget(Object tgt, Object thiz) : target(tgt) && this(thiz)
pointcut notSelf(): selfAndTarget(tgt, thiz) && if(tgt != thiz)
person ramnivas    schedule 24.03.2011
comment
Спасибо, я не понимал, для чего нужны условные выражения, пока не увидел этот конкретный пример. Однако согласно документации AspectJ, если выражения pointcut будут оцениваться во время выполнения для каждой точки соединения кандидата: eclipse.org/aspectj/doc/released/adk15notebook/ Итак, в конечном итоге это немного более чистая версия того, что я уже делал в основной части моего совета как обходной путь. Я надеюсь, что кто-то может знать способ сделать это, что позволит статически исключить кандидатов в точки соединения. - person iainmcgin; 25.03.2011
comment
Невозможно статически определить, совпадает ли цель вызова с вызывающим абонентом. Объекты - это концепция среды выполнения, поэтому решение необходимо принимать во время выполнения. - person ramnivas; 25.03.2011
comment
В общем, да, наверное, вы правы. Существуют очевидные вызовы типа this.x (), но более широкий случай определения того, есть ли у вас псевдоним для самого себя, гораздо сложнее вывести статически. В любом случае, поскольку никто больше не предлагает никаких вариантов, я приму ваш ответ, спасибо за помощь! - person iainmcgin; 26.03.2011