@AspectJ pointcut для методов, которые переопределяют интерфейсный метод с аннотацией - PullRequest
16 голосов
/ 24 августа 2011

Как я могу написать pointj aspectj, который применяется к выполнению методов, которые переопределяют метод интерфейса с аннотацией?Например:

interface A {
  @MyAnnotation void method();
}
class B implements A {
  void method();
}

Pointcut execution(@MyAnnotation * *.*(..)) соответствует, только если B.method() содержит саму аннотацию.Есть ли другой способ сделать это?

Ответы [ 3 ]

12 голосов
/ 19 сентября 2011

Как указал Николас, в Аспекте это невозможно. Вот еще одно доказательство того, почему это невозможно (взято из http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-pointcuts-and-advice.html раздела «Наследование аннотаций и сопоставление точек»):

В соответствии со спецификацией Java 5 аннотации, не относящиеся к типу, не наследуются, а аннотации для типов наследуются только в том случае, если они имеют метааннотацию @Inherited. Вызов c2.aMethod (в данном примере это b.method ()) не сопоставляется, поскольку сопоставление точек соединения для модификаторов (модификаторов видимости, аннотаций и предложения throws) основано на предмете точки соединения ( метод на самом деле вызывается).

Пострадав от этой же проблемы, я написал небольшой метод / библиотеку, которая позволяла бы вам создавать контрольные точки для таких методов. Вот как это будет работать для вашего примера:

myAnnotationIsExecuted(): execution(public * *.*(..)) && 
             if(implementsAnnotation("@MyAnnotation()", thisJoinPoint));

OR

myAnnotationIsExecuted(): execution(public * A+.*(..)) &&
             if(implementsAnnotation("@MyAnnotation()", thisJoinPoint));

Метод implementsAnnotation(String,JoinPoint) исходит из библиотеки; базовый метод, который проверяет, содержат ли реализованные методы указанную аннотацию.

Более подробную информацию о методе / библиотеке можно найти здесь .

4 голосов
/ 24 августа 2011

Обновление

Так как кажется, что это не может быть сделано весной (см. Оригинальный ответ), я бы сказал, что вам нужно добавить аннотацию к каждому методуна реализации классов.Существует очевидный способ сделать это, но я полагаю, что если вы ищете более автоматический способ, вам нужно будет написать его самостоятельно.

Я могу представить какой-то доморощенный постпроцессор, который будет выглядетьдля конкретной аннотации, скажем, @ApplyThisAnnotationToAllWhoInheritMe.Как только он находит эту аннотацию, он сканирует исходный код на предмет наследования элементов и, при необходимости, добавляет запрошенную аннотацию перед компиляцией.

Независимо от того, если вы используете Spring AOP для этого, кажется, что он должен быть включенметод реализации.Если классы, которые, как вы надеетесь, вам помогут, находятся вне вашего контроля, вам, возможно, придется написать собственный инструмент Spring AOP.

Оригинальный ответ

Из документации Spring 3.0 :

AspectJ следует правилу Java о том, что аннотации на интерфейсах не наследуются.

Я нашел этот бит в разделе7.8.2 Other Spring aspects for AspectJ, который является частью 7.8 Using AspectJ with Spring applications, что заставляет меня думать, что это глобальное правило.

2 голосов
/ 25 августа 2011
//introducing empty marker interface
declare parents : hasmethod(@MyAnnotation * *(..)) implements TrackedParentMarker;

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

Также вы должны включить флаг компилятора –XhasMember.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...