diff options
author | avasseur <avasseur> | 2005-10-21 10:20:14 +0000 |
---|---|---|
committer | avasseur <avasseur> | 2005-10-21 10:20:14 +0000 |
commit | 62a4476ca3ff54a75a1b435d8dfe49a0e29cbdc6 (patch) | |
tree | 7784a6f97c1de8d733aeb4cc1b2ad6d7c62c0aa7 /docs | |
parent | 3021284f5d910a406d26a01ce836bbb5f5cd6bfc (diff) | |
download | aspectj-62a4476ca3ff54a75a1b435d8dfe49a0e29cbdc6.tar.gz aspectj-62a4476ca3ff54a75a1b435d8dfe49a0e29cbdc6.zip |
docs for @AJ ITD
Diffstat (limited to 'docs')
-rw-r--r-- | docs/adk15ProgGuideDB/ataspectj.xml | 702 |
1 files changed, 424 insertions, 278 deletions
diff --git a/docs/adk15ProgGuideDB/ataspectj.xml b/docs/adk15ProgGuideDB/ataspectj.xml index 2836c5e08..dc614e3d3 100644 --- a/docs/adk15ProgGuideDB/ataspectj.xml +++ b/docs/adk15ProgGuideDB/ataspectj.xml @@ -6,27 +6,27 @@ <title>Introduction</title> <para>In addition to the familiar AspectJ code-based style of aspect - declaration, AspectJ 5 also supports an annotation-based style of - aspect declaration. We informally call the set of annotations that - support this development style the "@AspectJ" annotations.</para> + declaration, AspectJ 5 also supports an annotation-based style of + aspect declaration. We informally call the set of annotations that + support this development style the "@AspectJ" annotations.</para> <para> - AspectJ 5 allows aspects and their members to be specified using - either the code style or the annotation style. Whichever style you - use, the AspectJ weaver ensures that your program has exactly the - same semantics. It is, to quote a famous advertising campaign, - "a choice, not a compromise". The two styles can be mixed within - a single application, and even within a single source file, though - we doubt this latter mix will be recommended in practice. + AspectJ 5 allows aspects and their members to be specified using + either the code style or the annotation style. Whichever style you + use, the AspectJ weaver ensures that your program has exactly the + same semantics. It is, to quote a famous advertising campaign, + "a choice, not a compromise". The two styles can be mixed within + a single application, and even within a single source file, though + we doubt this latter mix will be recommended in practice. </para> <para> - The use of the @AspectJ annotations means that there are large - classes of AspectJ applications that can be compiled by a regular - Java 5 compiler, and subsequently woven by the AspectJ weaver (for - example, as an additional build stage, or as late as class load-time). - In this chapter we introduce the @AspectJ annotations and show how - they can be used to declare aspects and aspect members. + The use of the @AspectJ annotations means that there are large + classes of AspectJ applications that can be compiled by a regular + Java 5 compiler, and subsequently woven by the AspectJ weaver (for + example, as an additional build stage, or as late as class load-time). + In this chapter we introduce the @AspectJ annotations and show how + they can be used to declare aspects and aspect members. </para> </sect1> @@ -35,9 +35,10 @@ <title>Aspect Declarations</title> <para> - Aspect declarations are supported by the - <literal>org.aspectj.lang.annotation.Aspect</literal> annotation. - The declaration: + Aspect declarations are supported by the + <literal>org.aspectj.lang.annotation.Aspect</literal> + annotation. + The declaration: </para> <programlisting><![CDATA[ @@ -59,9 +60,10 @@ ]]></programlisting> <para>To specify an aspect an aspect instantiation model (the default is - singleton), provide the perclause as the - <literal>@Aspect</literal> value. - For example: + singleton), provide the perclause as the + <literal>@Aspect</literal> + value. + For example: </para> <programlisting><![CDATA[ @@ -69,29 +71,29 @@ public class Foo {} ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> <programlisting><![CDATA[ public aspect Foo perthis(execution(* abc..*(..))) {} ]]></programlisting> - <sect2 id="limitations" xreflabel="limitations"> - <title>Limitations</title> - - <para>Privileged aspects are not supported by the annotation style.</para> - <!-- - <programlisting><![CDATA[ - @Aspect(isPrivileged=true) - public class Foo {} - ]]></programlisting> + <sect2 id="limitations" xreflabel="limitations"> + <title>Limitations</title> - <para>is equivalent to...</para> + <para>Privileged aspects are not supported by the annotation style.</para> + <!-- + <programlisting><![CDATA[ + @Aspect(isPrivileged=true) + public class Foo {} + ]]></programlisting> - <programlisting><![CDATA[ - public privileged aspect Foo {} - ]]></programlisting> - --> - </sect2> + <para>is equivalent to...</para> + + <programlisting><![CDATA[ + public privileged aspect Foo {} + ]]></programlisting> + --> + </sect2> </sect1> @@ -99,36 +101,43 @@ <title>Pointcuts and Advice</title> <para> - Pointcut and advice declarations can be made using the + Pointcut and advice declarations can be made using the <literal>Pointcut, Before, After, AfterReturning, AfterThrowing,</literal> - and - <literal>Around</literal> annotations. + and + <literal>Around</literal> + annotations. </para> <sect2 id="pointcuts" xreflabel="pointcuts"> <title>Pointcuts</title> <para> - Pointcuts are specified using the - <literal>org.aspectj.lang.annotation.Pointcut</literal> annotation - on a method declaration. The method should have a + Pointcuts are specified using the + <literal>org.aspectj.lang.annotation.Pointcut</literal> + annotation + on a method declaration. The method should have a <literal>void</literal> - return type. The parameters of the method correspond to the parameters - of the pointcut. The modifiers of the method correspond to the modifiers - of the pointcut. + return type. The parameters of the method correspond to the parameters + of the pointcut. The modifiers of the method correspond to the modifiers + of the pointcut. </para> <para> - As a general rule, the - <literal>@Pointcut</literal> annotated method must have an empty method body - and must not have any - <literal>throws</literal> clause. If formal are bound (using - <literal>args(), target(), this(), @args(), @target(), @this(), @annotation())</literal> in the - pointcut, then they must appear in the method signature. + As a general rule, the + <literal>@Pointcut</literal> + annotated method must have an empty method body + and must not have any + <literal>throws</literal> + clause. If formal are bound (using + <literal>args(), target(), this(), @args(), @target(), @this(), @annotation())</literal> + in the + pointcut, then they must appear in the method signature. </para> <para> - The <literal>if()</literal> pointcut is treated specially and is discussed in a later section. + The + <literal>if()</literal> + pointcut is treated specially and is discussed in a later section. </para> <para>Here is a simple example of a pointcut declaration in both code and @AspectJ styles:</para> @@ -138,9 +147,9 @@ void anyCall() {} ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ pointcut anyCall() : call(* *.*(..)); ]]></programlisting> @@ -152,45 +161,47 @@ void someCall(int i, Foo callee) {} ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ pointcut anyCall(int i, Foo callee) : call(* *.*(int)) && args(i) && target(callee); ]]></programlisting> - <para>An example with modifiers (it is also good to remember that Java 5 annotations are not inherited):</para> + <para>An example with modifiers (it is also good to remember that Java 5 annotations are not + inherited):</para> <programlisting><![CDATA[ @Pointcut("") protected abstract void anyCall(); ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ protected abstract pointcut anyCall(); ]]></programlisting> - <sect3> - <title>Type references inside @AspectJ annotations</title> - - <para> - Using the code style, types referenced in pointcut expressions are - resolved with respect to the imported types in the compilation unit. - When using the annotation style, types referenced in pointcut - expressions are resolved in the absence of any imports and so have - to be fully qualified if they are not by default visible to the - declaring type (outside of the declaring package and - <literal>java.lang</literal>). This - does not apply to type patterns with wildcards, which are always resolved - in a global scope. - </para> - - <para> - Consider the following compilation unit: - </para> - - <programlisting><![CDATA[ + <sect3> + <title>Type references inside @AspectJ annotations</title> + + <para> + Using the code style, types referenced in pointcut expressions are + resolved with respect to the imported types in the compilation unit. + When using the annotation style, types referenced in pointcut + expressions are resolved in the absence of any imports and so have + to be fully qualified if they are not by default visible to the + declaring type (outside of the declaring package and + <literal>java.lang</literal> + ). This + does not apply to type patterns with wildcards, which are always resolved + in a global scope. + </para> + + <para> + Consider the following compilation unit: + </para> + + <programlisting><![CDATA[ package org.aspectprogrammer.examples; import java.util.List; @@ -204,11 +215,11 @@ } ]]></programlisting> - <para> - Using the annotation style this would be written as: - </para> + <para> + Using the annotation style this would be written as: + </para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ package org.aspectprogrammer.examples; import java.util.List; // redundant but harmless @@ -225,44 +236,57 @@ } ]]></programlisting> - </sect3> - - <sect3> - <title>if() pointcut expressions</title> - - <para>In code style, it is possible to use the <literal>if(...)</literal> poincut to define - a conditional pointcut expression which will be evaluated at runtime for each candidate join point. - The <literal>if(...)</literal> - body can be any valid Java boolean expression, and can use any exposed formal, as well as the join point forms - <literal>thisJoinPoint, thisJoinPointStaticPart and thisJoinPointEnclosingStaticPart</literal>. - </para> - - <para> - When using the annotation style, it would be really a pain to write a valid Java expression within - the annotation value so the syntax differs sligthly, whilst providing the very same - semantics and runtime behaviour. An <literal>if()</literal> pointcut expression can be - declared in an <literal>@Pointcut</literal>, but must either an empty body, or be one - of the expression <literal>if(true)</literal> or <literal>if(false)</literal>. The annotated - method must be public, static, and return a boolean. The body of the method contains the - condition to be evaluated. For example: - </para> - - <programlisting><![CDATA[ + </sect3> + + <sect3> + <title>if() pointcut expressions</title> + + <para>In code style, it is possible to use the + <literal>if(...)</literal> + poincut to define + a conditional pointcut expression which will be evaluated at runtime for each candidate join point. + The + <literal>if(...)</literal> + body can be any valid Java boolean expression, and can use any exposed formal, as well as the join + point forms + <literal>thisJoinPoint, thisJoinPointStaticPart and thisJoinPointEnclosingStaticPart</literal> + . + </para> + + <para> + When using the annotation style, it would be really a pain to write a valid Java expression within + the annotation value so the syntax differs sligthly, whilst providing the very same + semantics and runtime behaviour. An + <literal>if()</literal> + pointcut expression can be + declared in an + <literal>@Pointcut</literal> + , but must either an empty body, or be one + of the expression + <literal>if(true)</literal> + or + <literal>if(false)</literal> + . The annotated + method must be public, static, and return a boolean. The body of the method contains the + condition to be evaluated. For example: + </para> + + <programlisting><![CDATA[ @Pointcut("call(* *.*(int)) && args(i) && if()") public static boolean someCallWithIfTest(int i) { return i > 0; } ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ pointcut someCallWithIfTest(int i) : call(* *.*(int)) && args(i) && if(i > 0); ]]></programlisting> - <para> and the following is also a valid form:</para> + <para>and the following is also a valid form:</para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ static int COUNT = 0; @Pointcut("call(* *.*(int)) && args(i) && if()") @@ -288,22 +312,41 @@ */ ]]></programlisting> - <para> - It is thus possible with the annotation style to use the <literal>if()</literal> pointcut - only within an <literal>@Pointcut</literal> expression. The <literal>if()</literal> must not contain any - body. The annotated <literal>@Pointcut</literal> method must then be of the form <literal>public static boolean</literal> - and can use formal bindings as usual. - Extra <emphasis>implicit</emphasis> arguments of type JoinPoint, JoinPoint.StaticPart and JoinPoint.EnclosingStaticPart can also be used - (this is not permitted for regular annotated pointcuts not using the <literal>if()</literal> form). - </para> - - <para> - The special forms <literal>if(true)</literal> and <literal>if(false)</literal> can be used in a more - general way and don't imply that the pointcut method must have a body. - You can thus write <literal>@Before("somePoincut() && if(false)")</literal>. - </para> - - </sect3> + <para> + It is thus possible with the annotation style to use the + <literal>if()</literal> + pointcut + only within an + <literal>@Pointcut</literal> + expression. The + <literal>if()</literal> + must not contain any + body. The annotated + <literal>@Pointcut</literal> + method must then be of the form + <literal>public static boolean</literal> + and can use formal bindings as usual. + Extra + <emphasis>implicit</emphasis> + arguments of type JoinPoint, JoinPoint.StaticPart and JoinPoint.EnclosingStaticPart can also be used + (this is not permitted for regular annotated pointcuts not using the + <literal>if()</literal> + form). + </para> + + <para> + The special forms + <literal>if(true)</literal> + and + <literal>if(false)</literal> + can be used in a more + general way and don't imply that the pointcut method must have a body. + You can thus write + <literal>@Before("somePoincut() && if(false)")</literal> + . + </para> + + </sect3> </sect2> @@ -311,38 +354,41 @@ <title>Advice</title> <para>In this section we first discuss the use of annotations for - simple advice declarations. Then we show how + simple advice declarations. Then we show how <literal>thisJoinPoint</literal> - and its siblings are handled in the body of advice and discuss the - treatment of - <literal>proceed</literal> in around advice. + and its siblings are handled in the body of advice and discuss the + treatment of + <literal>proceed</literal> + in around advice. </para> <para>Using the annotation style, an advice declaration is written as - a regular Java method with one of the + a regular Java method with one of the <literal>Before, After, AfterReturning, - AfterThrowing,</literal> or - <literal>Around</literal> annotations. Except in - the case of around advice, the method should return void. The method should - be declared public. + AfterThrowing,</literal> + or + <literal>Around</literal> + annotations. Except in + the case of around advice, the method should return void. The method should + be declared public. </para> <para>A method that has an advice annotation is treated exactly as an - advice declaration by AspectJ's weaver. This includes the join points that - arise when the advice is executed (an adviceexecution join point, not a - method execution join point).</para> + advice declaration by AspectJ's weaver. This includes the join points that + arise when the advice is executed (an adviceexecution join point, not a + method execution join point).</para> <para>The following example shows a simple before advice declaration in - both styles:</para> + both styles:</para> - <programlisting><![CDATA[ + <programlisting><![CDATA[ @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") public void callFromFoo() { System.out.println("Call from Foo"); } ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> <programlisting><![CDATA[ before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { @@ -351,37 +397,38 @@ ]]></programlisting> - <!-- - AMC: enhanced adviceexecution pointcuts and @AdviceName will most likely not make AJ5 1.5.0 - - <para>Notice one slight difference between the two advice declarations: in - the annotation style, the advice has a name, "callFromFoo". Even though - advice cannot be invoked explicitly, this name is useful in join point - matching when advising advice execution. For this reason, and to preserve - exact semantic equivalence between the two styles, we also support the - <literal>org.aspectj.lang.annotation.AdviceName</literal> annotation. - The exact equivalent declarations are: - </para> + <!-- + AMC: enhanced adviceexecution pointcuts and @AdviceName will most likely not make AJ5 1.5.0 - <programlisting><![CDATA[ - @AdviceName("callFromFoo") - before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { - System.out.println("Call from Foo"); - } + <para>Notice one slight difference between the two advice declarations: in + the annotation style, the advice has a name, "callFromFoo". Even though + advice cannot be invoked explicitly, this name is useful in join point + matching when advising advice execution. For this reason, and to preserve + exact semantic equivalence between the two styles, we also support the + <literal>org.aspectj.lang.annotation.AdviceName</literal> annotation. + The exact equivalent declarations are: + </para> - is equivalent to... + <programlisting><![CDATA[ + @AdviceName("callFromFoo") + before() : call(* org.aspectprogrammer..*(..)) && this(Foo) { + System.out.println("Call from Foo"); + } - @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") - public void callFromFoo() { - System.out.println("Call from Foo"); - } - ]]></programlisting> - - --> + is equivalent to... + + @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") + public void callFromFoo() { + System.out.println("Call from Foo"); + } + ]]></programlisting> + + --> <para>If the advice body needs to know which particular - <literal>Foo</literal> instance - is making the call, just add a parameter to the advice declaration. + <literal>Foo</literal> + instance + is making the call, just add a parameter to the advice declaration. </para> <programlisting><![CDATA[ @@ -390,7 +437,7 @@ } ]]></programlisting> - <para>can be written as:</para> + <para>can be written as:</para> <programlisting><![CDATA[ @Before("call(* org.aspectprogrammer..*(..)) && this(foo)") @@ -400,13 +447,14 @@ ]]></programlisting> <para>If the advice body needs access to - <literal>thisJoinPoint</literal>, - <literal>thisJoinPointStaticPart</literal>, - <literal>thisEnclosingJoinPointStaticPart</literal> then these need to - be declared as additional method parameters when using the annotation - style. <!-- TODO AV - not any more - In AspectJ 1.5.0 we require that these parameters be declared - first in the parameter list, in later releases we may relax this - requirement.--> + <literal>thisJoinPoint</literal> + , + <literal>thisJoinPointStaticPart</literal> + , + <literal>thisEnclosingJoinPointStaticPart</literal> + then these need to + be declared as additional method parameters when using the annotation + style. </para> <programlisting><![CDATA[ @@ -416,8 +464,8 @@ + thisJoinPoint); } ]]></programlisting> - - <para>is equivalent to...</para> + + <para>is equivalent to...</para> <programlisting><![CDATA[ before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) { @@ -425,7 +473,7 @@ + thisJoinPoint); } ]]></programlisting> - + <para>Advice that needs all three variables would be declared:</para> <programlisting><![CDATA[ @@ -438,29 +486,36 @@ ]]></programlisting> <para> - <literal>JoinPoint.EnclosingStaticPart</literal> is a new (empty) sub-interface - of - <literal>JoinPoint.StaticPart</literal> which allows the AspectJ weaver to - distinguish based on type which of - <literal>thisJoinPointStaticPart</literal> and - <literal>thisEnclosingJoinPointStaticPart</literal> should be passed in a given - parameter position. + <literal>JoinPoint.EnclosingStaticPart</literal> + is a new (empty) sub-interface + of + <literal>JoinPoint.StaticPart</literal> + which allows the AspectJ weaver to + distinguish based on type which of + <literal>thisJoinPointStaticPart</literal> + and + <literal>thisEnclosingJoinPointStaticPart</literal> + should be passed in a given + parameter position. </para> <para> - <literal>After</literal> advice declarations take exactly the same form - as - <literal>Before</literal>, as do the forms of + <literal>After</literal> + advice declarations take exactly the same form + as + <literal>Before</literal> + , as do the forms of <literal>AfterReturning</literal> - and - <literal>AfterThrowing</literal> that do not expose the return type or - thrown exception respectively. + and + <literal>AfterThrowing</literal> + that do not expose the return type or + thrown exception respectively. </para> <para> - To expose a return value with after returning advice simply declare the returning - parameter as a parameter in the method body and bind it with the "returning" - attribute: + To expose a return value with after returning advice simply declare the returning + parameter as a parameter in the method body and bind it with the "returning" + attribute: </para> <programlisting><![CDATA[ @@ -475,7 +530,7 @@ } ]]></programlisting> - <para>is equivalent to...</para> + <para>is equivalent to...</para> <programlisting><![CDATA[ after() returning : criticalOperation() { @@ -488,19 +543,22 @@ ]]></programlisting> <para>(Note the use of the "pointcut=" prefix in front of the pointcut - expression in the returning case).</para> + expression in the returning case).</para> <para>After throwing advice works in a similar fashion, using the - <literal>throwing</literal> attribute when needing to expose a - thrown exception. + <literal>throwing</literal> + attribute when needing to expose a + thrown exception. </para> <para>For around advice, we have to tackle the problem of - <literal>proceed</literal>. - One of the design goals for the annotation style is that a large class of - AspectJ applications should be compilable with a standard Java 5 compiler. - A straight call to - <literal>proceed</literal> inside a method body: + <literal>proceed</literal> + . + One of the design goals for the annotation style is that a large class of + AspectJ applications should be compilable with a standard Java 5 compiler. + A straight call to + <literal>proceed</literal> + inside a method body: </para> <programlisting><![CDATA[ @@ -512,9 +570,11 @@ <para>will result in a "No such method" compilation error. For this - reason AspectJ 5 defines a new sub-interface of - <literal>JoinPoint</literal>, - <literal>ProceedingJoinPoint</literal>. + reason AspectJ 5 defines a new sub-interface of + <literal>JoinPoint</literal> + , + <literal>ProceedingJoinPoint</literal> + . </para> <programlisting><![CDATA[ @@ -550,7 +610,7 @@ ]]></programlisting> - <para>is equivalent to:</para> + <para>is equivalent to:</para> <programlisting><![CDATA[ public aspect ProceedAspect { @@ -563,9 +623,8 @@ ]]></programlisting> - -<para>Note that the ProceedingJoinPoint does not need to be passed to the proceed(..) arguments. -</para> + <para>Note that the ProceedingJoinPoint does not need to be passed to the proceed(..) arguments. + </para> </sect2> </sect1> @@ -573,20 +632,19 @@ <sect1 id="ataspectj-itds"> <title>Inter-type Declarations</title> - <para><emphasis>The features described in this section will not be supported until the - AspectJ 5 M4 milestone build.</emphasis></para> - <para> - Inter-type declarations are challenging to support using an annotation style. - It's very important to preserve the exact same semantics between the code style - and the annotation style. We also want to support compilation of a large set - of AspectJ applications using a standard Java 5 compiler. For these reasons, in - the initial release of AspectJ 5 we will only support inter-type declarations - on interfaces using the annotation style. + Inter-type declarations are challenging to support using an annotation style. + It's very important to preserve the exact same semantics between the code style + and the annotation style. We also want to support compilation of a large set + of AspectJ applications using a standard Java 5 compiler. For these reasons, in + the initial release of AspectJ 5 we will only support inter-type declarations + backed by interfaces when using the annotation style - which means it is not possible to + introduce constructors or fields, as it would not be not possible to call those unless already + weaved and available on a binary form. </para> <para> - Consider the following aspect: + Consider the following aspect: </para> <programlisting><![CDATA[ @@ -609,15 +667,18 @@ ]]></programlisting> <para> - This declares an interface - <literal>Moody</literal>, and then makes two - inter-type declarations on the interface - a field that is private to the - aspect, and a method that returns the mood. Within the body of the inter-type - declared method - <literal>getMoody</literal>, the type of + This declares an interface + <literal>Moody</literal> + , and then makes two + inter-type declarations on the interface - a field that is private to the + aspect, and a method that returns the mood. Within the body of the inter-type + declared method + <literal>getMoody</literal> + , the type of <literal>this</literal> - is - <literal>Moody</literal> (the target type of the inter-type declaration). + is + <literal>Moody</literal> + (the target type of the inter-type declaration). </para> <para>Using the annotation style this aspect can be written: @@ -627,12 +688,13 @@ @Aspect public class MoodIndicator { + // this interface can be outside of the aspect public interface Moody { Mood getMood(); }; - @DeclareParents("org.xzy..*") - class MoodyImpl implements Moody { + // this implementation can be outside of the aspect + public class MoodyImpl implements Moody { private Mood mood = Mood.HAPPY; public Mood getMood() { @@ -640,6 +702,12 @@ } } + // here is the actual ITD syntax when using @AspectJ + // public static is mandatory + // the field type must be the introduced interface. It can't be a class. + @DeclareParents("org.xzy..*") + public static Moody introduced = new MoodyImpl(); + @Before("execution(* *.*(..)) && this(m)") void feelingMoody(Moody m) { System.out.println("I'm feeling " + m.getMood()); @@ -648,22 +716,88 @@ ]]></programlisting> <para> - This is very similar to the mixin mechanism supported by AspectWerkz. The - effect of the - <literal>@DeclareParents</literal> annotation is equivalent to - a declare parents statement that all types matching the type pattern implement - the interface implemented by the annotated class. In addition, the member - declarations within the annotated class are treated as inter-type declarations - on the implemented interface. Note how this scheme operates within the constraints - of Java type checking and ensures that - <literal>this</literal> has access - to the exact same set of members as in the code style example. + This is very similar to the mixin mechanism supported by AspectWerkz. The + effect of the + <literal>@DeclareParents</literal> + annotation is equivalent to + a declare parents statement that all types matching the type pattern implement + the interface whose @DeclareParents annotated aspect' field is type of (in this case Moody). + Each method declaration of this interface are treated as inter-type declarations. + Note how this scheme operates within the constraints + of Java type checking and ensures that + <literal>this</literal> + has access + to the exact same set of members as in the code style example. + </para> + + <para> + Note that it is illegal to use the @DeclareParents annotation on an aspect' field whose type + is not an interface. Indeed, the interface is the inter-type declaration contract that dictates + which methods are introduced. + </para> + + <para> + It is important to remember that the @DeclareParents annotated aspect' field that serves as a host + for the inter-type declaration must be <literal>public static</literal> and <literal>initialized by some means</literal>. + The weaved code will indeed delegate calls to this field when f.e. invoking: + </para> + + <programlisting><![CDATA[ + // this type will be affected by the inter-type declaration as the type pattern match + package org.xyz; + public class MoodTest { + + public void test() { + // see here the cast to the introduced interface + Mood mood = ((Moody)this).getMood(); + // will delegate to the aspect field "introduced" that host this inter-type declaration + ... + } + } + ]]></programlisting> + + <para> + It is perfectly possible to use an IoC framework to initialize the @DeclaredParents aspect' field. You must + ensure though that the aspect field will be initialed prior the first inter-type declaration invocation it hosts. + </para> + + + <para> + If you need to only introduce a marker interface which defines no method - such as <literal>java.io.Serializable</literal> + it is possible to use the following syntax. + </para> + + <para> + Consider the following aspect: + </para> + + <programlisting><![CDATA[ + public aspect SerializableMarker { + + declare parents : org.xyz..* implements Serializable; + } + ]]></programlisting> + + <para>Using the annotation style this aspect can be written: + </para> + + <programlisting><![CDATA[ + @Aspect + public class SerializableMarker { + + @DeclareImplements("org.xyz..*") + Serializable introducedNoMethods; + } + ]]></programlisting> + + <para> + The <literal>@DeclareImplements</literal> annotation on the aspect' field dictates the type pattern + on which to introduce the marker interface. </para> - <para>The annotated class may only extend - <literal>Object</literal>, and may - only implement a single interface. The interface implemented by the class may - itself extend other interfaces. + <para> + In that case, as there is no method introduced, it is perfectly possible to have the aspect' field + private, or not initialized. Remember that the field' type must be the introduced interface and cannot be class. </para> </sect1> @@ -672,17 +806,23 @@ <title>Declare statements</title> <para>The previous section on inter-type declarations covered the case - of declare parents ... implements. The 1.5.0 release of AspectJ 5 will - not support annotation style declarations for declare parents ... extends - and declare soft (programs with these declarations would not in general - be compilable by a regular Java 5 compiler, reducing the priority of - their implementation). These may be supported in a future release.</para> - - <para>Declare precedence and declare annotation - <emphasis>will</emphasis> - be supported. For declare precedence, use the + of declare parents ... implements. The 1.5.0 release of AspectJ 5 will + not support annotation style declarations for declare parents ... extends + and declare soft (programs with these declarations would not in general + be compilable by a regular Java 5 compiler, reducing the priority of + their implementation). These may be supported in a future release.</para> + + <para> + Declare annotation is not supported neither in the 1.5.0 release of AspectJ 5. Given that Java 5 + compilers enforce the annotation target (@java.lang.annotation.Target) to be respected, this would cause + adding a lot of dummy members in the aspect (such as dummy constructors, methods etc), which would break the + object oriented design of the @AspectJ aspect itself. + </para> + + <para>Declare precedence <emphasis>is</emphasis> + supported. For declare precedence, use the <literal>@DeclarePrecedence</literal> - annotation as in the following example: + annotation as in the following example: </para> <programlisting><![CDATA[ @@ -702,12 +842,16 @@ } ]]></programlisting> + <!-- + note: below is not supported for now. <para> - Declare annotation is supported via annotations on a dummy type member. If the - <literal>Target</literal> specification of the annotation allows it, use a field, - otherwise declare a member of the type required by the - <literal>Target</literal>. - For example: + Declare annotation is supported via annotations on a dummy type member. If the + <literal>Target</literal> + specification of the annotation allows it, use a field, + otherwise declare a member of the type required by the + <literal>Target</literal> + . + For example: </para> <programlisting><![CDATA[ @@ -740,18 +884,18 @@ <para> <emphasis>Note: Declare annotation is not available in AspectJ 1.5 M3 and syntax may change - when the design and implementation is complete.</emphasis> + when the design and implementation is complete.</emphasis> </para> - + --> <para>We also support annotation style declarations for declare warning and - declare error - any corresponding warnings and errors will be emitted at - weave time, not when the aspects containing the declarations are compiled. - (This is the same behaviour as when using declare warning or error with the - code style). Declare warning and error declarations are made by annotating - a string constant whose value is the message to be issued.</para> + declare error - any corresponding warnings and errors will be emitted at + weave time, not when the aspects containing the declarations are compiled. + (This is the same behaviour as when using declare warning or error with the + code style). Declare warning and error declarations are made by annotating + a string constant whose value is the message to be issued.</para> <para>Note that the String must be a constant and not the result of the invocation - of a static method for example.</para> + of a static method for example.</para> <programlisting><![CDATA[ declare warning : call(* javax.sql..*(..)) && !within(org.xyz.daos..*) @@ -784,19 +928,21 @@ <title>aspectOf() and hasAspect() methods</title> <para>A central part of AspectJ's programming model is that aspects - written using the code style and compiled using ajc support - <literal>aspectOf</literal> and - <literal>hasAspect</literal> static - methods. When developing an aspect using the annotation style and compiling - using a regular Java 5 compiler, these methods will not be visible to the - compiler and will result in a compilation error if another part of the - program tries to call them. + written using the code style and compiled using ajc support + <literal>aspectOf</literal> + and + <literal>hasAspect</literal> + static + methods. When developing an aspect using the annotation style and compiling + using a regular Java 5 compiler, these methods will not be visible to the + compiler and will result in a compilation error if another part of the + program tries to call them. </para> <para>To provide equivalent support for AspectJ applications compiled with - a standard Java 5 compiler, AspectJ 5 defines the + a standard Java 5 compiler, AspectJ 5 defines the <literal>Aspects</literal> - utility class: + utility class: </para> <programlisting><![CDATA[ |