Abstract
This guide describes the changes to the AspectJ language in AspectJ 5. These include support for Java 5 (Tiger) features, support for an annotation-based development style for aspects, and new reflection and tools APIs. If you are new to AspectJ, we recommend you start by reading the programming guide.
Table of Contents
Table of Contents
Many of the extensions to the AspectJ language to address the new features of Java 5 are derived from a simple set of principles for join point matching. In this section, we outline these principles as a foundation for understanding the matching rules in the presence of annotations, generics, covariance, varargs, and autoboxing.
AspectJ supports 11 different kinds of join points. These are
the method call, method execution, constructor call,
constructor execution, field get, field set, pre-initialization,
initialization, static initialization, handler, and
advice execution join points.
The kinded pointcut designators match
based on the kind of a join point. These are the call,
execution, get, set, preinitialization, initialization,
staticinitialization, handler, and adviceexecution
designators.
A kinded pointcut is written using patterns, some of which
match based on signature, and some of which
match based on modifiers. For example, in
the call pointcut designator:
call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern)
the modifiers matching patterns are ModifierPattern
and ThrowsPattern, and the signature matching patterns
are TypePattern TypePattern.IdPattern(TypePatternList).
A join point has potentially multiple signatures, but only one set of modifiers. A kinded primitive pointcut matches a particular join point if and only if:
These rules make it very easily to quickly determine whether a given pointcut matches a given join point. In the next two sections, we describe what the signature(s) of a join point are, and what the subjects of join points are.
Call, execution, get, and set join points may potentially have multiple signatures. All other join points have exactly one signature. The following table summarizes the constituent parts of a join point signature for the different kinds of join point.
| Join Point Kind | Return Type | Declaring Type | Id | Parameter Types | Field Type | Exception Type |
|---|---|---|---|---|---|---|
| Method call | + | + | + | + | ||
| Method execution | + | + | + | + | ||
| Constructor call | + | + | ||||
| Constructor execution | + | + | ||||
| Field get | + | + | + | |||
| Field set | + | + | + | |||
| Pre-initialization | + | + | ||||
| Initialization | + | + | ||||
| Static initialization | + | |||||
| Handler | + | |||||
| Advice execution | + | + |
Note that whilst an advice excetution join point has a
signature comprising the declaring type of the advice and the
advice parameter types, the adviceexecution
pointcut designator does not support matching based on this
signature.
The signatures for most of the join point kinds should be self-explanatory, except for field get and set, and method call and execution join points, which can have multiple signatures. Each signature of a method call or execution join point has the same id and parameter types, but the declaring type and return type (with covariance) may vary. Each signature of a field get or set join point has the same id and field type, but the declaring type may vary.
The following sections examine signatures for these join points in more detail.
For a call join point where a call is made to a method
m(parameter_types) on a target type T (where
T is the static type of the target):
T t = new T();
t.m("hello"); <= call join point occurs when this line is executed
Then the signature R(T) T.m(parameter_types) is a signature
of the call join point, where R(T) is the return
type of m in T, and
parameter_types are the parameter types of
m. If T itself does not
declare a definition of m(parameter_types), then
R(T) is the return type in the definition of
m that T inherits. Given the
call above, and the definition of T.m:
interface Q {
R m(String s);
}
class P implements Q {
R m(String s) {...}
}
class S extends P {
R' m(String s) {...}
}
class T extends S {}
Then R' T.m(String) is a signature of the
call join point for t.m("hello").
For each ancestor (super-type) A of T,
if m(parameter_types) is defined for that super-type, then
R(A) A.m(parameter_types) is a signature of the call join
point, where R(A) is the return type of
m(parameter_types) as defined in A, or as inherited
by A if A itself does not
provide a definition of m(parameter_types).
Continuing the example from above,we can deduce that
R' S.m(String)
R P.m(String)
R Q.m(String)
are all additional signatures for the call join point arising
from the call t.m("hello"). Thus this call
join point has four signatures in total. Every signature has the same
id and parameter types, and a different declaring type.
Join point signatures for execution join points are defined in a similar manner to signatures for call join points. Given the hierarchy:
interface Q {
R m(String s);
}
class P implements Q {
R m(String s) {...}
}
class S extends P {
R' m(String s) {...}
}
class T extends S { }
class U extends T {
R' m(String s) {...}
}
Then the execution join point signatures arising as a result
of the call to u.m("hello") are:
R' U.m(String)
R' S.m(String)
R P.m(String)
R Q.m(String)
Each signature has the same id and parameter types, and a
different declaring type. There is one signature for each type
that provides its own declaration of the method. Hence in this
example there is no signature R' T.m(String)
as T does not provide its own declaration of
the method.
For a field get join point where an access is made to a field
f of type F
on a object with declared type T, then
F T.f is a signature of the get join point.
If T does not directly declare a member
f, then for each super type S
of T, up to and including the most specific
super type of T that does declare the member
f, F S.f is a signature
of the join point. For example, given the hierarchy:
class P {
F f;
}
class S extends P {
F f;
}
class T extends S { }
Then the join point signatures for a field get join point of
the field f on an object with declared type
T are:
F S.f
F T.f
The signatures for a field set join point are derived in an identical manner.
Every join point has a single set of modifiers - these include
the standard Java modifiers such as public, private,
static, abstract etc., any annotations, and the throws
clauses of methods and constructors. These modifiers are the
modifiers of the subject of the join point.
The following table defines the join point subject for each kind of join point.
| Join Point Kind | Subject |
|---|---|
| Method call | The method picked out by Java as the static target of the method call. |
| Method execution | The method that is executing. |
| Constructor call | The constructor being called. |
| Constructor execution | The constructor executing. |
| Field get | The field being accessed. |
| Field set | The field being set. |
| Pre-initialization | The first constructor executing in this constructor chain. |
| Initialization | The first constructor executing in this constructor chain. |
| Static initialization | The type being initialized. |
| Handler | The declared type of the exception being handled. |
| Advice execution | The advice being executed. |
For example, given the following types
public class X {
@Foo
protected void doIt() {...}
}
public class Y extends X {
public void doIt() {...}
}
Then the modifiers for a call to (Y y) y.doIt()
are simply {public}. The modifiers for a call to
(X x) x.doIt() are {@Foo,protected}.
A join point has potentially multiple signatures, but only one set of modifiers. A kinded primitive pointcut matches a particular join point if and only if:
Given the hierarchy
interface Q {
R m(String s);
}
class P implements Q {
@Foo
public R m(String s) {...}
}
class S extends P {
@Bar
public R' m(String s) {...}
}
class T extends S {}
and the program fragment:
P p = new P();
S s = new S();
T t = new T();
...
p.m("hello");
s.m("hello");
t.m("hello");
The the pointcut call(@Foo R P.m(String)) matches the
call p.m("hello") since both the signature and the
modifiers match. It does not match the call s.m("hello")
because even though the signature pattern matches one of the signatures
of the join point, the modifiers pattern does not match the modifiers of
the method m in S which is the static target of the call.
The pointcut call(R' m(String)) matches the
calls t.m("hello") and s.m("hello").
It does not match the call p.m("hello") since the
signature pattern does not match any signature for the call join point
of m in P.
Table of Contents
This section provides the essential information about annotations in Java 5 needed to understand how annotations are treated in AspectJ 5. For a full introduction to annotations in Java, please see the documentation for the Java 5 SDK.
Java 5 introduces annotation types which can
be used to express metadata relating to program members in the
form of annotations. Annotations in Java 5
can be applied to package and type declarations (classes,
interfaces, enums, and annotations), constructors, methods,
fields, parameters, and variables. Annotations are specified in the
program source by using the @ symbol. For example,
the following piece of code uses the @Deprecated
annotation to indicate that the obsoleteMethod()
has been deprecated:
@Deprecated
public void obsoleteMethod() { ... }
Annotations may be marker annotations, single-valued annotations, or multi-valued annotations. Annotation types with no members or that provide default values for all members may be used simply as marker annotations, as in the deprecation example above. Single-value annotation types have a single member, and the annotation may be written in one of two equivalent forms:
@SuppressWarnings({"unchecked"})
public void someMethod() {...}
or
@SuppressWarnings(value={"unchecked"})
public void someMethod() {...}
Multi-value annotations must use the member-name=value
syntax to specify annotation values. For example:
@Authenticated(role="supervisor",clearanceLevel=5)
public void someMethod() {...}
Annotations can have one of three retention policies:
Annotations with source-file retention are read by the
compiler during the compilation process, but are not
rendered in the generated .class files.
This is the default retention policy. Annotations
with class-file retention are read by the compiler
and also retained in the generated
.class files.
Annotations with runtime retention are read by the
compiler, retained in the generated
.class files, and also made available
at runtime.
Local variable annotations are not retained in class files (or at runtime) regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.
Java 5 supports a new interface,
java.lang.reflect.AnnotatedElement, that is
implemented by the reflection classes in Java (Class,
Constructor,
Field, Method, and
Package). This interface gives you access
to annotations that have runtime retention via
the getAnnotation, getAnnotations,
and isAnnotationPresent. Because annotation types are
just regular Java classes, the annotations returned by these methods
can be queried just like any regular Java object.
It is important to understand the rules relating to inheritance of annotations, as these have a bearing on join point matching based on the presence or absence of annotations.
By default annotations are not inherited. Given the following program
@MyAnnotation
class Super {
@Oneway public void foo() {}
}
class Sub extends Super {
public void foo() {}
}
Then Sub does not have
the MyAnnotation annotation, and
Sub.foo() is not an @Oneway
method, despite the fact that it overrides
Super.foo() which is.
If an annotation type has the meta-annotation @Inherited
then an annotation of that type on a class will cause
the annotation to be inherited by sub-classes. So, in the example
above, if the MyAnnotation type had the
@Inherited attribute, then Sub
would have the MyAnnotation annotation.
@Inherited annotations are not inherited when used to
annotate anything other than a type. A type
that implements one or more interfaces never inherits any annotations from
the interfaces it implements.
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...
}
}
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.
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.An annotation pattern element has one of two basic forms:
These simple elements may be negated using !, and
combined by simple concatentation. The pattern @Foo @Boo
matches an annotated element that has both an annotation of type Foo
and an annotation of type Boo.
Some examples of annotation patterns follow:
Matches any annotated element which has an annotation of
type Immutable.
Matches any annotated element which does not have an annotation of
type Persistent.
Matches any annotated element which has both an annotation of type Foo and
an annotation of type Goo.
Matches any annotated element which has either an annotation of a type matching
the type pattern (Foo || Goo).
In other words, an annotated element with either an
annotation of type Foo or
an annotation of type Goo (or both). (The parenthesis are required in this example).
Matches any annotated element which has either an annotation of a type matching
the type pattern (org.xyz..*).
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).
AspectJ 1.5 extends type patterns to allow an optional AnnotationPattern
prefix.
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+)*
Note that in most cases when annotations are used as part of a type pattern,
the parenthesis are required (as in (@Foo Hello+)). In
some cases (such as a type pattern used within a within or
handler
pointcut expression), the parenthesis are optional:
OptionalParensTypePattern := AnnotationPattern? TypePattern
The following examples illustrate the use of annotations in type patterns:
Matches any type with an @Immutable annotation.
Matches any type which does not have an @Immutable annotation.
Matches any type in the org.xyz or org.abc
packages with the @Immutable annotation.
Matches a type Foo or any of its subtypes, which have the @Immutable
annotation, or a type Goo.
Matches any type in a package beginning with the prefix org.xyz,
which has either the @Immutable annotation or the
@NonPersistent annotation.
Matches any type in a package beginning with the prefix org.xyz,
which has both an @Immutable annotation and an
@NonPersistent annotation.
Matches any type in a package beginning with the prefix org.xyz,
which has an inheritable annotation. The annotation pattern
@(@Inherited *) matches any annotation of a type matching the
type pattern @Inherited *, which in turn matches any type with the
@Inherited annotation.
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.
The @annotation pointcut designator matches any
join point where the subject of the join point has
an annotation of the given type. Like the other @pcds, it can also be
used for context exposure.
AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
The subject of a join point is defined in the table in chapter one of this guide.
Access to annotation information on members at a matched join point is also available
through the getSignature method of the JoinPoint
and JoinPoint.StaticPart interfaces. The Signature
interfaces are extended with additional operations that provide access to the
java.lang.reflect Method, Field and
Constructor objects on which annnotations can be queried. The following fragment
illustrates an example use of this interface to access annotation information.
Pattern? ture Patterns
A FieldPattern can optionally specify an annotation-matching
pattern as the first element:
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
DotOrDotDot := '.' | '..'
SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
If present, the AnnotationPattern restricts matches to fields with
annotations that match the pattern. For example:
Matches a field of any type and any name, that has an annotation of
type @SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of type List, and has an annotation of type
@SensitiveData
Matches a member field of a type in a package with prefix org.xzy,
where the field is of a type which has a @SensitiveData annotation.
Matches a field with an annotation @Foo, of a type with an
annotation @Goo, declared in a type with annotation
@Hoo.
Matches a field with an annotation @Persisted and
an annotation @Classified.
A MethodPattern can optionally specify an annotation-matching
pattern as the first element.
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)*
A ConstructorPattern has the form
ConstructorPattern :=
AnnotationPattern? ConstructorModifiersPattern?
(TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
ThrowsPattern?
ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
ConstructorModifier := 'public' | 'private' | 'protected'
The optional AnnotationPattern at the beginning of a
method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
Matches a method with any return type and any name, that has an annotation of
type @Oneway.
Matches a method with the @Transaction annotation,
declared in a type with the @Persistent annotation, and
in a package beginning with the org.xyz prefix.
Matches any method taking at least one parameter, where the parameter
type has an annotation @Immutable.
Matches any join point where the code executing is declared in a
type with an @Secure
annotation. The format of the within pointcut designator
in AspectJ 5 is 'within' '(' OptionalParensTypePattern ')'.
Matches the staticinitialization join point of any type with the
@Persistent annotation. The format of the
staticinitialization pointcut designator
in AspectJ 5 is 'staticinitialization' '(' OptionalParensTypePattern ')'.
Matches a call to a method with a @Oneway annotation.
The execution of any public method in a package with prefix
org.xyz, where the method returns an
immutable result.
Matches the set of any cachable field.
Matches the handler join point for the handling of any exception that is
not Catastrophic. The format of the handler
pointcut designator in AspectJ 5 is 'handler' '(' OptionalParensTypePattern ')'.
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 @args, @this, @target,
@within, @withincode, and @annotation
It is a compilation error to attempt to match on an annotation type
that does not have runtime retention using @this, @target
or @args. It is a compilation error to attempt to use
any of these designators to expose an annotation value that does not
have runtime retention.
The this(), target(), and
args() 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 : @this() (read, "this
annotation"), @target(), and @args().
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:
AtThis := '@this' '(' AnnotationOrIdentifer ')'
AtTarget := '@target' '(' AnnotationOrIdentifier ')'
AnnotationOrIdentifier := FullyQualifiedName | Identifier
AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
AnnotationsOrIdentifiersPattern :=
'..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
'*' (',' AnnotationsOrIdentifiersPattern)*
AnnotationsOrIdentifiersPatternAfterDotDot :=
AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
'*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
The forms of @this() and @target() 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
this (or target, respectively) has an
annotation of the specified type. For example:
Matches any join point where the object currently bound to 'this'
has an annotation of type Foo.
Matches a call to any object where the target of the call has
a @Classified annotation.
Annotations can be exposed as context in the body of advice by
using the forms of @this(), @target() and
@args() that use bound variables in the place
of annotation names. For example:
pointcut callToClassifiedObject(Classified classificationInfo) : call(* *(..)) && @target(classificationInfo); pointcut txRequiredMethod(Tx transactionAnnotation) : execution(* *(..)) && @this(transactionAnnotation) && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
The @args pointcut designator behaves as its args
counterpart, matching join points based on number and position of arguments, and
supporting the * wildcard and at most one ..
wildcard. An annotation at a given position in an @args 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:
/** * 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);
In addition to accessing annotation information at runtime through context binding,
access to AnnotatedElement information is also available
reflectively with the body of advice through the thisJoinPoint,
thisJoinPointStaticPart, and
thisEnclosingJoinPointStaticPart 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:
Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations(); Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
The @within and @withincode pointcut designators
match any join point where the executing code is defined within a type (@within),
or a method/constructor (@withincode) that has an annotation of the specified
type. The form of these designators is:
AtWithin := '@within' '(' AnnotationOrIdentifier ')'
AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
Some examples of using these designators follow:
Matches any join point where the executing code is defined
within a type which has an annotation of type Foo.
Matches any join point where the executing code is defined
in a method or constructor which has an annotation of type @Critical,
and exposes the value of the annotation in the parameter
c.