123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- <chapter id="jpsigs" xreflabel="Join Point Signatures">
-
- <title>Join Point Signatures</title>
-
- <para>
- 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.
- </para>
-
- <sect1 id="join-point-matching">
- <title>Join Point Matching</title>
-
- <para>AspectJ supports 11 different kinds of join points. These are
- the <literal>method call, method execution, constructor call,
- constructor execution, field get, field set, pre-initialization,
- initialization, static initialization, handler,</literal> and
- <literal>advice execution</literal> join points.</para>
-
- <para>The <emphasis>kinded</emphasis> pointcut designators match
- based on the kind of a join point. These are the <literal>call,
- execution, get, set, preinitialization, initialization,
- staticinitialization, handler,</literal> and <literal>adviceexecution</literal>
- designators.</para>
-
- <para>A kinded pointcut is written using patterns, some of which
- match based on <emphasis>signature</emphasis>, and some of which
- match based on <emphasis>modifiers</emphasis>. For example, in
- the <literal>call</literal> pointcut designator:</para>
-
- <programlisting><![CDATA[
- call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern)
- ]]></programlisting>
-
- <para>the modifiers matching patterns are <literal>ModifierPattern</literal>
- and <literal>ThrowsPattern</literal>, and the signature matching patterns
- are <literal>TypePattern TypePattern.IdPattern(TypePatternList)</literal>.
- </para>
-
- <para>
- A join point has potentially multiple signatures, but only one set of
- modifiers. <emphasis>A kinded primitive pointcut matches a particular join point
- if and only if</emphasis>:
- </para>
-
- <orderedlist>
- <listitem>They are of the same kind</listitem>
- <listitem>The signature pattern (exactly) matches at least one
- signature of the join point</listitem>
- <listitem>The modifiers pattern matches the modifiers of the
- subject of the join point</listitem>
- </orderedlist>
-
- <para>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.</para>
-
- </sect1>
-
- <sect1 id="join-point-signatures">
- <title>Join Point Signatures</title>
-
- <para>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.</para>
-
- <informaltable>
- <tgroup cols="7">
- <thead>
- <row>
- <entry>Join Point Kind</entry>
- <entry>Return Type</entry>
- <entry>Declaring Type</entry>
- <entry>Id</entry>
- <entry>Parameter Types</entry>
- <entry>Field Type</entry>
- <entry>Exception Type</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>Method call</entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Method execution</entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Constructor call</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Constructor execution</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Field get</entry>
- <entry></entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- </row>
- <row>
- <entry>Field set</entry>
- <entry></entry>
- <entry>+</entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- </row>
- <row>
- <entry>Pre-initialization</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Initialization</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Static initialization</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- <entry></entry>
- <entry></entry>
- </row>
- <row>
- <entry>Handler</entry>
- <entry></entry>
- <entry></entry>
- <entry></entry>
- <entry></entry>
- <entry></entry>
- <entry>+</entry>
- </row>
- <row>
- <entry>Advice execution</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry>+</entry>
- <entry></entry>
- <entry></entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- <para>Note that whilst an advice execution join point has a
- signature comprising the declaring type of the advice and the
- advice parameter types, the <literal>adviceexecution</literal>
- pointcut designator does not support matching based on this
- signature.</para>
-
- <para>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.
- </para>
-
- <para>The following sections examine signatures for these join points
- in more detail.</para>
-
- <sect2 id="method-call-join-point-signatures" xreflabel="method-call-join-point-signatures">
- <title>Method call join point signatures</title>
-
- <para>
- For a call join point where a call is made to a method
- <literal>m(parameter_types)</literal> on a target type <literal>T</literal> (where
- <literal>T</literal> is the static type of the target):
- </para>
-
- <programlisting><![CDATA[
- T t = new T();
- t.m("hello"); <= call join point occurs when this line is executed
- ]]></programlisting>
-
- <para>
- Then the signature <literal>R(T) T.m(parameter_types)</literal> is a signature
- of the call join point, where <literal>R(T)</literal> is the return
- type of <literal>m</literal> in <literal>T</literal>, and
- <literal>parameter_types</literal> are the parameter types of
- <literal>m</literal>. If <literal>T</literal> itself does not
- declare a definition of <literal>m(parameter_types)</literal>, then
- <literal>R(T)</literal> is the return type in the definition of
- <literal>m</literal> that <literal>T</literal> inherits. Given the
- call above, and the definition of <literal>T.m</literal>:
- </para>
-
- <programlisting><![CDATA[
- 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 {}
- ]]></programlisting>
-
- <para>Then <literal>R' T.m(String)</literal> is a signature of the
- call join point for <literal>t.m("hello")</literal>.</para>
-
- <para>
- For each ancestor (super-type) <literal>A</literal> of <literal>T</literal>,
- if <literal>m(parameter_types)</literal> is defined for that super-type, then
- <literal>R(A) A.m(parameter_types)</literal> is a signature of the call join
- point, where <literal>R(A)</literal> is the return type of <literal>
- m(parameter_types)</literal> as defined in <literal>A</literal>, or as inherited
- by <literal>A</literal> if <literal>A</literal> itself does not
- provide a definition of <literal>m(parameter_types)</literal>.
- </para>
-
- <para>
- Continuing the example from above,we can deduce that
- </para>
-
- <programlisting><![CDATA[
- R' S.m(String)
- R P.m(String)
- R Q.m(String)
- ]]></programlisting>
-
- <para>are all additional signatures for the call join point arising
- from the call <literal>t.m("hello")</literal>. Thus this call
- join point has four signatures in total. Every signature has the same
- id and parameter types, and a different declaring type.</para>
-
- </sect2>
-
- <sect2 id="method-execution-join-point-signatures" xreflabel="method-execution-join-point-signatures">
- <title>Method execution join point signatures</title>
-
- <para>Join point signatures for execution join points are defined
- in a similar manner to signatures for call join points. Given the
- hierarchy:
- </para>
-
-
- <programlisting><![CDATA[
- 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) {...}
- }
- ]]></programlisting>
-
- <para>Then the execution join point signatures arising as a result
- of the call to <literal>u.m("hello")</literal> are: </para>
-
- <programlisting><![CDATA[
- R' U.m(String)
- R' S.m(String)
- R P.m(String)
- R Q.m(String)
- ]]></programlisting>
-
- <para>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 <literal>R' T.m(String)</literal>
- as <literal>T</literal> does not provide its own declaration of
- the method.</para>
-
- </sect2>
-
- <sect2 id="field-get-and-set-join-point-signatures" xreflabel="field-get-and-set-join-point-signatures">
- <title>Field get and set join point signatures</title>
-
- <para>
- For a field get join point where an access is made to a field
- <literal>f</literal> of type <literal>F</literal>
- on a object with declared type <literal>T</literal>, then
- <literal>F T.f</literal> is a signature of the get join point.
- </para>
-
- <para>
- If <literal>T</literal> does not directly declare a member
- <literal>f</literal>, then for each super type <literal>S</literal>
- of <literal>T</literal>, up to and including the most specific
- super type of <literal>T</literal> that does declare the member
- <literal>f</literal>, <literal>F S.f</literal> is a signature
- of the join point. For example, given the hierarchy:
- </para>
-
- <programlisting><![CDATA[
- class P {
- F f;
- }
-
- class S extends P {
- F f;
- }
-
- class T extends S { }
- ]]></programlisting>
-
- <para>
- Then the join point signatures for a field get join point of
- the field <literal>f</literal> on an object with declared type
- <literal>T</literal> are:
- </para>
-
- <programlisting><![CDATA[
- F S.f
- F T.f
- ]]></programlisting>
-
- <para>The signatures for a field set join point are derived in an
- identical manner.</para>
-
- </sect2>
-
- </sect1>
-
- <sect1 id="join-point-modifiers">
- <title>Join Point Modifiers</title>
-
- <para>Every join point has a single set of modifiers - these include
- the standard Java modifiers such as <literal>public, private,
- static, abstract</literal> etc., any annotations, and the throws
- clauses of methods and constructors. These modifiers are the
- modifiers of the <emphasis>subject</emphasis> of the join point.</para>
-
- <para>
- The following table defines the join point subject for each kind
- of join point.
- </para>
-
- <informaltable>
- <tgroup cols="2">
- <thead>
- <row>
- <entry>Join Point Kind</entry>
- <entry>Subject</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>Method call</entry>
- <entry>The method picked out by Java as
- the static target of the method call.</entry>
- </row>
- <row>
- <entry>Method execution</entry>
- <entry>The method that is executing.</entry>
- </row>
- <row>
- <entry>Constructor call</entry>
- <entry>The constructor being called.</entry>
- </row>
- <row>
- <entry>Constructor execution</entry>
- <entry>The constructor executing.</entry>
- </row>
- <row>
- <entry>Field get</entry>
- <entry>The field being accessed.</entry>
- </row>
- <row>
- <entry>Field set</entry>
- <entry>The field being set.</entry>
- </row>
- <row>
- <entry>Pre-initialization</entry>
- <entry>The first constructor executing in
- this constructor chain.</entry>
- </row>
- <row>
- <entry>Initialization</entry>
- <entry>The first constructor executing in
- this constructor chain.</entry>
- </row>
- <row>
- <entry>Static initialization</entry>
- <entry>The type being initialized.</entry>
- </row>
- <row>
- <entry>Handler</entry>
- <entry>The declared type of the
- exception being handled.</entry>
- </row>
- <row>
- <entry>Advice execution</entry>
- <entry>The advice being executed.</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
-
- <para>For example, given the following types</para>
-
- <programlisting><![CDATA[
- public class X {
- @Foo
- protected void doIt() {...}
- }
-
- public class Y extends X {
- public void doIt() {...}
- }
- ]]></programlisting>
-
- <para>Then the modifiers for a call to <literal>(Y y) y.doIt()</literal>
- are simply <literal>{public}</literal>. The modifiers for a call to
- <literal>(X x) x.doIt()</literal> are <literal>{@Foo,protected}</literal>.
- </para>
-
- </sect1>
-
- <sect1 id="join-point-matching-summary">
- <title>Summary of Join Point Matching</title>
-
- <para>
- A join point has potentially multiple signatures, but only one set of
- modifiers. <emphasis>A kinded primitive pointcut matches a particular join point
- if and only if</emphasis>:
- </para>
-
- <orderedlist>
- <listitem>They are of the same kind</listitem>
- <listitem>The signature pattern (exactly) matches at least one
- signature of the join point</listitem>
- <listitem>The modifiers pattern matches the modifiers of the
- subject of the join point</listitem>
- </orderedlist>
-
- <para>Given the hierarchy</para>
-
- <programlisting><![CDATA[
- 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 {}
- ]]></programlisting>
-
- <para>and the program fragment:</para>
-
- <programlisting><![CDATA[
- P p = new P();
- S s = new S();
- T t = new T();
- ...
- p.m("hello");
- s.m("hello");
- t.m("hello");
- ]]></programlisting>
-
- <para>
- The the pointcut <literal>call(@Foo R P.m(String))</literal> matches the
- call <literal>p.m("hello")</literal> since both the signature and the
- modifiers match. It does not match the call <literal>s.m("hello")</literal>
- 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.
- </para>
-
- <para>The pointcut <literal>call(R' m(String))</literal> matches the
- calls <literal>t.m("hello")</literal> and <literal>s.m("hello")</literal>.
- It does not match the call <literal>p.m("hello")</literal> since the
- signature pattern does not match any signature for the call join point
- of m in P.</para>
- </sect1>
-
- </chapter>
|