AspectJ 5 supports annotations on aspects, and on method, field, constructor, advice, and inter-type declarations within aspects. Method and advice parameters may also be annotated. Annotations are not permitted on pointcut declarations or on declare statements.
The following example illustrates the use of annotations in aspects:
@AspectAnnotation public abstract aspect ObserverProtocol { @InterfaceAnnotation interface Observer {} @InterfaceAnnotation interface Subject {} @ITDFieldAnnotation private List<Observer> Subject.observers; @ITDMethodAnnotation public void Subject.addObserver(Observer o) { observers.add(o); } @ITDMethodAnnotation public void Subject.removeObserver(Observer o) { observers.remove(o); } @MethodAnnotation private void notifyObservers(Subject subject) { for(Observer o : subject.observers) notifyObserver(o,subject); } /** * Delegate to concrete sub-aspect the actual form of * notification for a given type of Observer. */ @MethodAnnotation protected abstract void notifyObserver(Observer o, Subject s); /* no annotations on pointcuts */ protected abstract pointcut observedEvent(Subject subject); @AdviceAnnotation after(Subject subject) returning : observedEvent(subject) { notifyObservers(subject); } }
An annotation on an aspect will be inherited by sub-aspects, iff it has the @Inherited meta-annotation.
AspectJ 5 supports a new XLint warning, "the pointcut associated with this advice does not match any join points". The warning is enabled by default and will be emitted by the compiler if the pointcut expression associated with an advice statement can be statically determined to not match any join points. The warning can be suppressed for an individual advice statement by using the @SuppressAjWarnings({"adviceDidNotMatch"}) annotation. This works in the same way as the Java 5 SuppressWarnings annotation (See JLS 9.6.1.5), but has class file retention.
import org.aspectj.lang.annotation.SuppressAjWarnings; public aspect AnAspect { pointcut anInterfaceOperation() : execution(* AnInterface.*(..)); @SuppressAjWarnings // may not match if there are no implementers of the interface... before() : anInterfaceOperation() { // do something... } @SuppressAjWarnings("adviceDidNotMatch") // alternate form after() returning : anInterfaceOperation() { // do something... } }