<html><head> | |
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
<title>Join Point Matching based on Annotations</title><link rel="stylesheet" href="aspectj-docs.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.44"><link rel="home" href="index.html" title="The AspectJTM 5 Development Kit Developer's Notebook"><link rel="up" href="annotations.html" title="Chapter 2. Annotations"><link rel="previous" href="annotations-aspectmembers.html" title="Annotating Aspects"><link rel="next" href="annotations-decp.html" title="Using Annotations with declare statements"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Join Point Matching based on Annotations</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="annotations-aspectmembers.html">Prev</a> </td><th width="60%" align="center">Chapter 2. Annotations</th><td width="20%" align="right"> <a accesskey="n" href="annotations-decp.html">Next</a></td></tr></table><hr></div><div class="sect1"><a name="annotations-pointcuts-and-advice"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="annotations-pointcuts-and-advice"></a>Join Point Matching based on Annotations</h2></div></div><p> | |
This section discusses changes to type pattern and signature pattern matching in | |
AspectJ 5 that support matching join points based on the presence or absence of | |
annotations. We then discuss means of exposing annotation values within the body | |
of advice. | |
</p><div class="sect2"><a name="annotation-patterns"></a><div class="titlepage"><div><h3 class="title"><a name="annotation-patterns"></a>Annotation Patterns</h3></div></div><p> | |
For any kind of annotated element (type, method, constructor, package, etc.), | |
an annotation pattern can be used to match against the set of annotations | |
on the annotated element. Annotation patterns are defined by the following | |
grammar. | |
</p><pre class="programlisting"> | |
AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern* | |
AnnotationTypePattern := FullyQualifiedName | | |
'(' TypePattern ')' | |
FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* | |
</pre><p>In simple terms, an annotation pattern element has one of two basic | |
forms:</p><div class="itemizedlist"><ul><li><a name="d0e792"></a>@<qualified-name>, for example, @Foo, or | |
@org.xyz.Foo.</li><li><a name="d0e794"></a>@(<type-pattern>), for example, @(org.xyz..*), or | |
@(Foo || Boo)</li></ul></div><p>These simple elements may be negated using <tt>!</tt>, and | |
combined by simple concatentation. The pattern <tt>@Foo @Boo</tt> | |
matches an annotated element that has both an annotation of type <tt>Foo</tt> | |
and an annotation of type <tt>Boo</tt>.</p><p>Some examples of annotation patterns follow:</p><div class="variablelist"><dl><dt><a name="d0e813"></a><span class="term">@Immutable</span></dt><dd><p><a name="d0e816"></a> | |
Matches any annotated element which has an annotation of | |
type <tt>Immutable</tt>. | |
</p></dd><dt><a name="d0e822"></a><span class="term">!@Persistent</span></dt><dd><p><a name="d0e825"></a> | |
Matches any annotated element which does not have an annotation of | |
type <tt>Persistent</tt>. | |
</p></dd><dt><a name="d0e831"></a><span class="term">@Foo @Goo</span></dt><dd><p><a name="d0e834"></a> | |
Matches any annotated element which has both an annotation of type <tt>Foo</tt> and | |
an annotation of type <tt>Goo</tt>. | |
</p></dd><dt><a name="d0e843"></a><span class="term">@(Foo || Goo)</span></dt><dd><p><a name="d0e846"></a> | |
Matches any annotated element which has either an annotation of a type matching | |
the type pattern <tt>(Foo || Goo)</tt>. | |
In other words, an annotated element with either an | |
annotation of type <tt>Foo</tt> or | |
an annotation of type <tt>Goo</tt> (or both). (The parenthesis are required in this example). | |
</p></dd><dt><a name="d0e858"></a><span class="term">@(org.xyz..*)</span></dt><dd><p><a name="d0e861"></a> | |
Matches any annotated element which has either an annotation of a type matching | |
the type pattern <tt>(org.xyz..*)</tt>. | |
In other words, an annotated element with an annotation that is declared in the | |
org.xyz package or a sub-package. (The parenthesis are required in this example). | |
</p></dd></dl></div></div><div class="sect2"><a name="type-patterns"></a><div class="titlepage"><div><h3 class="title"><a name="type-patterns"></a>Type Patterns</h3></div></div><p>AspectJ 1.5 extends type patterns to allow an optional <tt>AnnotationPattern</tt> | |
prefix. (Extensions to this definition for generics are shown in the next chapter).</p><pre class="programlisting"> | |
TypePattern := SimpleTypePattern | | |
'!' TypePattern | | |
'(' AnnotationPattern? TypePattern ')' | |
TypePattern '&&' TypePattern | | |
TypePattern '||' TypePattern | |
SimpleTypePattern := DottedNamePattern '+'? '[]'* | |
DottedNamePattern := FullyQualifiedName RestOfNamePattern? | | |
'*' NotStarNamePattern? | |
RestOfNamePattern := '..' DottedNamePattern | | |
'*' NotStarNamePattern? | |
NotStarNamePattern := FullyQualifiedName RestOfNamePattern? | | |
'..' DottedNamePattern | |
FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* | |
</pre><p>Note that in most cases when annotations are used as part of a type pattern, | |
the parenthesis are required (as in <tt>(@Foo Hello+)</tt>). In | |
some cases (such as a type pattern used within a <tt>this</tt> | |
pointcut expression, the parenthesis are optional:</p><pre class="programlisting"> | |
OptionalParensTypePattern := AnnotationPattern? TypePattern | |
</pre><p> | |
The following examples illustrate the use of annotations in type | |
patterns: | |
</p><div class="variablelist"><dl><dt><a name="d0e890"></a><span class="term">(@Immutable *)</span></dt><dd><p><a name="d0e893"></a> | |
Matches any type with an <tt>@Immutable</tt> annotation. | |
</p></dd><dt><a name="d0e899"></a><span class="term">(!@Immutable *)</span></dt><dd><p><a name="d0e902"></a> | |
Matches any type which does not have an <tt>@Immutable</tt> annotation. | |
</p></dd><dt><a name="d0e908"></a><span class="term"> (@Immutable (org.xyz.* || org.abc.*))</span></dt><dd><p><a name="d0e911"></a> | |
Matches any type in the <tt>org.xyz</tt> or <tt>org.abc</tt> | |
packages with the <tt>@Immutable</tt> annotation. | |
</p></dd><dt><a name="d0e923"></a><span class="term">((@Immutable Foo+) || Goo)</span></dt><dd><p><a name="d0e926"></a> | |
Matches a type <tt>Foo</tt> or any of its subtypes, which have the <tt>@Immutable</tt> | |
annotation, or a type <tt>Goo</tt>. | |
</p></dd><dt><a name="d0e938"></a><span class="term">((@(Immutable || NonPersistent) org.xyz..*)</span></dt><dd><p><a name="d0e941"></a> | |
Matches any type in a package beginning with the prefix <tt>org.xyz</tt>, | |
which has either the <tt>@Immutable</tt> annotation or the | |
<tt>@NonPersistent</tt> annotation. | |
</p></dd><dt><a name="d0e953"></a><span class="term">(@Immutable @NonPersistent org.xyz..*)</span></dt><dd><p><a name="d0e956"></a> | |
Matches any type in a package beginning with the prefix <tt>org.xyz</tt>, | |
which has both an <tt>@Immutable</tt> annotation and an | |
<tt>@NonPersistent</tt> annotation. | |
</p></dd><dt><a name="d0e968"></a><span class="term"> (@(@Inherited *) org.xyz..*)</span></dt><dd><p><a name="d0e971"></a> | |
Matches any type in a package beginning with the prefix <tt>org.xyz</tt>, | |
which has an inheritable annotation. The annotation pattern | |
<tt>@(@Inherited *)</tt> matches any annotation of a type matching the | |
type pattern <tt>@Inherited *</tt>, which in turn matches any type with the | |
<tt>@Inherited</tt> annotation. | |
</p></dd></dl></div></div><div class="sect2"><a name="signaturePatterns"></a><div class="titlepage"><div><h3 class="title"><a name="signaturePatterns"></a>Signature Patterns</h3></div></div><p>A <tt>FieldPattern</tt> is described by the following | |
grammar:</p><pre class="programlisting"> | |
FieldPattern := | |
AnnotationPattern? FieldModifiersPattern? | |
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern | |
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern* | |
FieldModifier := 'public' | 'private' | 'protected' | 'static' | | |
'transient' | 'final' | |
DotOrDotDot := '.' | '..' | |
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? | |
</pre><p> | |
The optional <tt>AnnotationPattern</tt> restricts matches to fields with | |
annotations that match the pattern. For example: | |
</p><div class="variablelist"><dl><dt><a name="d0e1002"></a><span class="term">@SensitiveData * *</span></dt><dd><p><a name="d0e1005"></a> | |
Matches a field of any type and any name, that has an annotation of | |
type <tt>@SensitiveData</tt> | |
</p></dd><dt><a name="d0e1011"></a><span class="term">@SensitiveData List org.xyz..*.*</span></dt><dd><p><a name="d0e1014"></a> | |
Matches a member field of a type in a package with prefix <tt>org.xzy</tt>, | |
where the field is of type <tt>List</tt>, and has an annotation of type | |
<tt>@SensitiveData</tt> | |
</p></dd><dt><a name="d0e1026"></a><span class="term">(@SensitiveData *) org.xyz..*.*</span></dt><dd><p><a name="d0e1029"></a> | |
Matches a member field of a type in a package with prefix <tt>org.xzy</tt>, | |
where the field is of a type which has a <tt>@SensitiveData</tt> annotation. | |
</p></dd><dt><a name="d0e1038"></a><span class="term">@Foo (@Goo *) (@Hoo *).*</span></dt><dd><p><a name="d0e1041"></a> | |
Matches a field with an annotation <tt>@Foo</tt>, of a type with an | |
annotation <tt>@Goo</tt>, declared in a type with annotation | |
<tt>@Hoo</tt>. | |
</p></dd><dt><a name="d0e1053"></a><span class="term">@Persisted @Classified * *</span></dt><dd><p><a name="d0e1056"></a> | |
Matches a field with an annotation <tt>@Persisted</tt> and | |
an annotation <tt>@Classified</tt>. | |
</p></dd></dl></div><p>A <tt>MethodPattern</tt> is of the form</p><pre class="programlisting"> | |
MethodPattern := | |
AnnotationPattern? MethodModifiersPattern? TypePattern | |
(TypePattern DotOrDotDot)? SimpleNamePattern | |
'(' FormalsPattern ')'ThrowsPattern? | |
MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern* | |
MethodModifier := 'public' | 'private' | 'protected' | 'static' | | |
'synchronized' | 'final' | |
FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* | | |
OptionalParensTypePattern (',' FormalsPattern)* | | |
TypePattern '...' | |
FormalsPatternAfterDotDot := | |
OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | | |
TypePattern '...' | |
ThrowsPattern := 'throws' TypePatternList | |
TypePatternList := TypePattern (',' TypePattern)* | |
</pre><p><span class="emphasis"><i>Note: compared to the previous version, this definition of MethodPattern does | |
not allow parameter annotation matching (only matching on annotations of parameter types).</i></span></p><p>A <tt>ConstructorPattern</tt> has the form</p><pre class="programlisting"> | |
ConstructorPattern := | |
AnnotationPattern? ConstructorModifiersPattern? | |
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' | |
ThrowsPattern? | |
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern* | |
ConstructorModifier := 'public' | 'private' | 'protected' | |
</pre><p> | |
The optional <tt>AnnotationPattern</tt> at the beginning of a | |
method or constructor pattern restricts matches to methods/constructors with | |
annotations that match the pattern. For example: | |
</p><div class="variablelist"><dl><dt><a name="d0e1088"></a><span class="term">@Oneway * *(..)</span></dt><dd><p><a name="d0e1091"></a> | |
Matches a method with any return type and any name, that has an annotation of | |
type <tt>@Oneway</tt>. | |
</p></dd><dt><a name="d0e1097"></a><span class="term">@Transaction * (@Persistent org.xyz..*).*(..)</span></dt><dd><p><a name="d0e1100"></a> | |
Matches a method with the <tt>@Transaction</tt> annotation, | |
declared in a type with the <tt>@Persistent</tt> annotation, and | |
in a package beginning with the <tt>org.xyz</tt> prefix. | |
</p></dd><dt><a name="d0e1112"></a><span class="term">* *.*(@Immutable *,..)</span></dt><dd><p><a name="d0e1115"></a> | |
Matches any method taking at least one parameter, where the parameter | |
type has an annotation <tt>@Immutable</tt>. | |
</p></dd></dl></div></div><div class="sect2"><a name="example-pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="example-pointcuts"></a>Example Pointcuts</h3></div></div><div class="variablelist"><dl><dt><a name="d0e1125"></a><span class="term">within(@Secure *)</span></dt><dd><p><a name="d0e1128"></a> | |
Matches any join point where the code executing is declared in a | |
type with an <tt>@Secure</tt> | |
annotation. The format of the <tt>within</tt> pointcut designator | |
in AspectJ 5 is <tt>'within' '(' OptionalParensTypePattern ')'</tt>. | |
</p></dd><dt><a name="d0e1140"></a><span class="term">staticinitialization(@Persistent *)</span></dt><dd><p><a name="d0e1143"></a> | |
Matches the staticinitialization join point of any type with the | |
<tt>@Persistent</tt> annotation. The format of the | |
<tt>staticinitialization</tt> pointcut designator | |
in AspectJ 5 is <tt>'staticinitialization' '(' OptionalParensTypePattern ')'</tt>. | |
</p></dd><dt><a name="d0e1155"></a><span class="term">call(@Oneway * *(..))</span></dt><dd><p><a name="d0e1158"></a> | |
Matches a call to a method with a <tt>@Oneway</tt> annotation. | |
</p></dd><dt><a name="d0e1164"></a><span class="term">execution(public (@Immutable *) org.xyz..*.*(..))</span></dt><dd><p><a name="d0e1167"></a> | |
The execution of any public method in a package with prefix | |
<tt>org.xyz</tt>, where the method returns an | |
immutable result. | |
</p></dd><dt><a name="d0e1173"></a><span class="term">set(@Cachable * *)</span></dt><dd><p><a name="d0e1176"></a> | |
Matches the set of any cachable field. | |
</p></dd><dt><a name="d0e1179"></a><span class="term">handler(!@Catastrophic *)</span></dt><dd><p><a name="d0e1182"></a> | |
Matches the handler join point for the handling of any exception that is | |
not <tt>Catastrophic</tt>. The format of the <tt>handler</tt> | |
pointcut designator in AspectJ 5 is <tt>'handler' '(' OptionalParensTypePattern ')'</tt>. | |
</p></dd></dl></div></div><div class="sect2"><a name="runtime-type-matching-and-context-exposure"></a><div class="titlepage"><div><h3 class="title"><a name="runtime-type-matching-and-context-exposure"></a>Runtime type matching and context exposure</h3></div></div><p>AspectJ 5 supports a set of "@" pointcut designators which | |
can be used both to match based on the presence of an annotation at | |
runtime, and to expose the annotation value as context in a pointcut or | |
advice definition. These designators are <tt>@args, @this, @target, | |
@within, @withincode</tt>, and <tt>@annotation</tt> | |
</p><p>It is a compilation error to attempt to match on an annotation type | |
that does not have runtime retention using <tt>@this, @target</tt> | |
or <tt>@args</tt>. It is a compilation error to attempt to use | |
any of these designators to expose an annotation value that does not | |
have runtime retention.</p><p> | |
The <tt>this()</tt>, <tt>target()</tt>, and | |
<tt>args()</tt> pointcut designators allow matching based | |
on the runtime type of an object, as opposed to the statically | |
declared type. In AspectJ 5, these designators are supplemented | |
with three new designators : <tt>@this()</tt> (read, "this | |
annotation"), <tt>@target()</tt>, and <tt>@args()</tt>. | |
</p><p> | |
Like their counterparts, these pointcut designators can be used | |
both for join point matching, and to expose context. The format of | |
these new designators is: | |
</p><pre class="programlisting"> | |
AtThis := '@this' '(' AnnotationOrIdentifer ')' | |
AtTarget := '@target' '(' AnnotationOrIdentifier ')' | |
AnnotationOrIdentifier := FullyQualifiedName | Identifier | |
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')' | |
AnnotationsOrIdentifiersPattern := | |
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | | |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | | |
'*' (',' AnnotationsOrIdentifiersPattern)* | |
AnnotationsOrIdentifiersPatternAfterDotDot := | |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | | |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | |
</pre><p> | |
The forms of <tt>@this()</tt> and <tt>@target()</tt> that | |
take a single annotation name are analogous to their counterparts that take | |
a single type name. They match at join points where the object bound to | |
<tt>this</tt> (or <tt>target</tt>, respectively) has an | |
annotation of the specified type. For example: | |
</p><div class="variablelist"><dl><dt><a name="d0e1252"></a><span class="term">@this(Foo)</span></dt><dd><p><a name="d0e1255"></a> | |
Matches any join point where the object currently bound to 'this' | |
has an annotation of type <tt>Foo</tt>. | |
</p></dd><dt><a name="d0e1261"></a><span class="term">call(* *(..)) && @target(Classified)</span></dt><dd><p><a name="d0e1264"></a> | |
Matches a call to any object where the target of the call has | |
a <tt>@Classified</tt> annotation. | |
</p></dd></dl></div><p> | |
Annotations can be exposed as context in the body of advice by | |
using the forms of <tt>@this(), @target()</tt> and | |
<tt>@args()</tt> that use bound variables in the place | |
of annotation names. For example: | |
</p><pre class="programlisting"> | |
pointcut callToClassifiedObject(Classified classificationInfo) : | |
call(* *(..)) && @target(classificationInfo); | |
pointcut txRequiredMethod(Tx transactionAnnotation) : | |
execution(* *(..)) && @this(transactionAnnotation) | |
&& if(transactionAnnotation.policy() == TxPolicy.REQUIRED); | |
</pre><p> | |
The <tt>@args</tt> pointcut designator behaves as its <tt>args</tt> | |
counterpart, matching join points based on number and position of arguments, and | |
supporting the <tt>*</tt> wildcard and at most one <tt>..</tt> | |
wildcard. An annotation at a given position in an <tt>@args</tt> expression | |
indicates that the runtime type of the argument in that position at a join point must | |
have an annotation of the indicated type. For example: | |
</p><pre class="programlisting"> | |
/** | |
* matches any join point with at least one argument, and where the | |
* type of the first argument has the @Classified annotation | |
*/ | |
pointcut classifiedArgument() : @args(Classified,..); | |
/** | |
* matches any join point with three arguments, where the third | |
* argument has an annotation of type @Untrusted. | |
*/ | |
pointcut untrustedData(Untrusted untrustedDataSource) : | |
@args(*,*,untrustedDataSource); | |
</pre><p> | |
<span class="emphasis"><i>Note: an alternative design would be to allow both annotation | |
patterns and type patterns to be specified in the existing args pcd. | |
This works well for matching, but is more awkward when it comes to | |
exposing context.</i></span> | |
</p><p>Access to <tt>AnnotatedElement</tt> information is available | |
reflectively with the body of advice through the <tt>thisJoinPoint</tt>, | |
<tt>thisJoinPointStaticPart</tt>, and | |
<tt>thisEnclosingJoinPointStaticPart</tt> variables. To access | |
annotations on the arguments, or object bound to this or target at a join | |
point you can use the following code fragments:</p><pre class="programlisting"> | |
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); | |
Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); | |
Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations(); | |
</pre><p> | |
<span class="emphasis"><i>Note: it would be nicer to provide direct helper methods in | |
the JoinPoint interface or a sub-interface that provide the annotations | |
directly, something like "AnnotatedElement getThisAnnotationInfo()". | |
The problem here is that the "AnnotatedElement" type is only in the | |
Java 5 runtime libraries, and we don't want to tie the AspectJ runtime | |
library to Java 5. A sub-interface and downcast solution could be used | |
if these helpers were felt to be sufficiently important.</i></span> | |
</p><p> | |
The <tt>@within</tt> and <tt>@withincode</tt> pointcut designators | |
match any join point where the executing code is defined within a type (<tt>@within</tt>), | |
or a method/constructor (<tt>@withincode</tt>) that has an annotation of the specified | |
type. The form of these designators is: | |
</p><pre class="programlisting"> | |
AtWithin := '@within' '(' AnnotationOrIdentifier ')' | |
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')' | |
</pre><p>Some examples of using these designators follow:</p><div class="variablelist"><dl><dt><a name="d0e1344"></a><span class="term">@within(Foo)</span></dt><dd><p><a name="d0e1347"></a> | |
Matches any join point where the executing code is defined | |
within a type which has an annotation of type <tt>Foo</tt>. | |
</p></dd><dt><a name="d0e1353"></a><span class="term">pointcut insideCriticalMethod(Critical c) : | |
@withincode(c);</span></dt><dd><p><a name="d0e1356"></a> | |
Matches any join point where the executing code is defined | |
in a method or constructor which has an annotation of type <tt>@Critical</tt>, | |
and exposes the value of the annotation in the parameter | |
<tt>c</tt>. | |
</p></dd></dl></div><p>The <tt>@annotation</tt> pointcut designator matches any | |
join point where the <span class="emphasis"><i>subject</i></span> of the join point has | |
an annotation of the given type. Like the other @pcds, it can also be | |
used for context exposure.</p><pre class="programlisting"> | |
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')' | |
</pre><p>The subject of a join point is defined in the table in chapter one of | |
this guide.</p><p> | |
Access to annotation information on members at a matched join point is also available | |
through the <tt>getSignature</tt> method of the <tt>JoinPoint</tt> | |
and <tt>JoinPoint.StaticPart</tt> interfaces. The <tt>Signature</tt> | |
interfaces are extended with additional operations that provide access to the | |
<tt>java.lang.reflect</tt> <tt>Method, Field</tt> and | |
<tt>Constructor</tt> objects on which annnotations can be queried. The following fragment | |
illustrates an example use of this interface to access annotation information. | |
</p><pre class="programlisting"> | |
Signature sig = thisJoinPointStaticPart.getSignature(); | |
AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType(); | |
if (sig instanceof MethodSignature) { | |
// this must be a call or execution join point | |
Method method = ((MethodSignature)sig).getMethod(); | |
} | |
</pre><p> | |
<span class="emphasis"><i>Note again that it would be nicer to add the method getAnnotationInfo | |
directly to MemberSignature, but this would once more couple the runtime library | |
to Java 5.</i></span> | |
</p><p> | |
The <tt>@this,@target</tt> and <tt>@args</tt> | |
pointcut designators can only be used to match against annotations | |
that have runtime retention. The <tt>@within, @withincode</tt> | |
and <tt>@annotation</tt> pointcut designators can only be used | |
to match against annotations that have at least class-file retention, and | |
if used in the binding form the annotation must have runtime retention. | |
</p></div><div class="sect2"><a name="package-and-parameter-annotations"></a><div class="titlepage"><div><h3 class="title"><a name="package-and-parameter-annotations"></a>Package and Parameter Annotations</h3></div></div><p> | |
<span class="emphasis"><i>Note: A previous design allowed package annotation patterns to be specified | |
directly in type patterns, and parameter annotation patterns to be | |
specified directly in method and constructor signature patterns. Because | |
this made some pointcut expressions hard to read and understand, we moved | |
in favour of the design presented below, which also has its drawbacks. | |
Matching on package and parameter annotations will be | |
deferred until after the 1.5.0 release so that we can gain more understanding | |
of the kinds of uses AspectJ users are making of annotations in pointcut | |
expressions before commiting to any one approach.</i></span> | |
</p></div><div class="sect2"><a name="annotation-inheritance-and-pointcut-matching"></a><div class="titlepage"><div><h3 class="title"><a name="annotation-inheritance-and-pointcut-matching"></a>Annotation Inheritance and pointcut matching</h3></div></div><p> | |
According to the Java 5 specification, non-type annotations are not | |
inherited, and annotations on types are only inherited if they have the | |
<tt>@Inherited</tt> meta-annotation. | |
Given the following program: | |
</p><pre class="programlisting"> | |
class C1 { | |
@SomeAnnotation | |
public void aMethod() {...} | |
} | |
class C2 extends C1 { | |
public void aMethod() {...} | |
} | |
class Main { | |
public static void main(String[] args) { | |
C1 c1 = new C1(); | |
C2 c2 = new C2(); | |
c1.aMethod(); | |
c2.aMethod(); | |
} | |
} | |
aspect X { | |
pointcut annotatedC2MethodCall() : | |
call(@SomeAnnotation * C2.aMethod()); | |
pointcut annotatedMethodCall() : | |
call(@SomeAnnotation * aMethod()); | |
} | |
</pre><p> | |
The pointcut <tt>annotatedC2MethodCall</tt> will not match anything | |
since the definition of <tt>aMethod</tt> in <tt>C2</tt> | |
does not have the annotation. | |
</p><p> | |
The pointcut <tt>annotatedMethodCall</tt> matches | |
<tt>c1.aMethod()</tt> but not <tt>c2.aMethod()</tt>. The call | |
to <tt>c2.aMethod</tt> is not matched because join point matching for | |
modifiers (the visibility modifiers, annotations, and throws clause) is based on | |
the subject of the join point (the method actually being called). | |
</p></div><div class="sect2"><a name="limitations"></a><div class="titlepage"><div><h3 class="title"><a name="limitations"></a>Limitations</h3></div></div><p> | |
It would be useful to be able to match join points based on | |
annotation values, rather than merely the presence of a | |
class-file retention annotation of a given type. This facility may be supported in a future version of AspectJ, by expanding the | |
definition of <tt>AnnotationPattern</tt>. Matching annotation values for | |
annotations with runtime retention can be done by exposing the annotation value | |
as a pointcut parameter and then using an <tt>if</tt> pointcut expression | |
to test the value. | |
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="annotations-aspectmembers.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="annotations-decp.html">Next</a></td></tr><tr><td width="40%" align="left">Annotating Aspects </td><td width="20%" align="center"><a accesskey="u" href="annotations.html">Up</a></td><td width="40%" align="right"> Using Annotations with declare statements</td></tr></table></div></body></html> |