From 62a4476ca3ff54a75a1b435d8dfe49a0e29cbdc6 Mon Sep 17 00:00:00 2001 From: avasseur Date: Fri, 21 Oct 2005 10:20:14 +0000 Subject: docs for @AJ ITD --- docs/adk15ProgGuideDB/ataspectj.xml | 702 ++++++++++++++++++++++-------------- 1 file changed, 424 insertions(+), 278 deletions(-) (limited to 'docs/adk15ProgGuideDB') 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 @@ Introduction 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. + 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. - 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. - 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. @@ -35,9 +35,10 @@ Aspect Declarations - Aspect declarations are supported by the - org.aspectj.lang.annotation.Aspect annotation. - The declaration: + Aspect declarations are supported by the + org.aspectj.lang.annotation.Aspect + annotation. + The declaration: To specify an aspect an aspect instantiation model (the default is - singleton), provide the perclause as the - @Aspect value. - For example: + singleton), provide the perclause as the + @Aspect + value. + For example: - is equivalent to... + is equivalent to... - - Limitations - - Privileged aspects are not supported by the annotation style. - - + is equivalent to... + + + --> + @@ -99,36 +101,43 @@ Pointcuts and Advice - Pointcut and advice declarations can be made using the + Pointcut and advice declarations can be made using the Pointcut, Before, After, AfterReturning, AfterThrowing, - and - Around annotations. + and + Around + annotations. Pointcuts - Pointcuts are specified using the - org.aspectj.lang.annotation.Pointcut annotation - on a method declaration. The method should have a + Pointcuts are specified using the + org.aspectj.lang.annotation.Pointcut + annotation + on a method declaration. The method should have a void - 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. - As a general rule, the - @Pointcut annotated method must have an empty method body - and must not have any - throws clause. If formal are bound (using - args(), target(), this(), @args(), @target(), @this(), @annotation()) in the - pointcut, then they must appear in the method signature. + As a general rule, the + @Pointcut + annotated method must have an empty method body + and must not have any + throws + clause. If formal are bound (using + args(), target(), this(), @args(), @target(), @this(), @annotation()) + in the + pointcut, then they must appear in the method signature. - The if() pointcut is treated specially and is discussed in a later section. + The + if() + pointcut is treated specially and is discussed in a later section. Here is a simple example of a pointcut declaration in both code and @AspectJ styles: @@ -138,9 +147,9 @@ void anyCall() {} ]]> - is equivalent to... + is equivalent to... - @@ -152,45 +161,47 @@ void someCall(int i, Foo callee) {} ]]> - is equivalent to... + is equivalent to... - - An example with modifiers (it is also good to remember that Java 5 annotations are not inherited): + An example with modifiers (it is also good to remember that Java 5 annotations are not + inherited): - is equivalent to... + is equivalent to... - - - Type references inside @AspectJ annotations - - - 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 - java.lang). This - does not apply to type patterns with wildcards, which are always resolved - in a global scope. - - - - Consider the following compilation unit: - - - + Type references inside @AspectJ annotations + + + 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 + java.lang + ). This + does not apply to type patterns with wildcards, which are always resolved + in a global scope. + + + + Consider the following compilation unit: + + + - - Using the annotation style this would be written as: - + + Using the annotation style this would be written as: + - - - - - if() pointcut expressions - - In code style, it is possible to use the if(...) poincut to define - a conditional pointcut expression which will be evaluated at runtime for each candidate join point. - The if(...) - body can be any valid Java boolean expression, and can use any exposed formal, as well as the join point forms - thisJoinPoint, thisJoinPointStaticPart and thisJoinPointEnclosingStaticPart. - - - - 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 if() pointcut expression can be - declared in an @Pointcut, but must either an empty body, or be one - of the expression if(true) or if(false). The annotated - method must be public, static, and return a boolean. The body of the method contains the - condition to be evaluated. For example: - - - + + + if() pointcut expressions + + In code style, it is possible to use the + if(...) + poincut to define + a conditional pointcut expression which will be evaluated at runtime for each candidate join point. + The + if(...) + body can be any valid Java boolean expression, and can use any exposed formal, as well as the join + point forms + thisJoinPoint, thisJoinPointStaticPart and thisJoinPointEnclosingStaticPart + . + + + + 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 + if() + pointcut expression can be + declared in an + @Pointcut + , but must either an empty body, or be one + of the expression + if(true) + or + if(false) + . The annotated + method must be public, static, and return a boolean. The body of the method contains the + condition to be evaluated. For example: + + + 0; } ]]> - is equivalent to... + is equivalent to... - 0); ]]> - and the following is also a valid form: + and the following is also a valid form: - - - It is thus possible with the annotation style to use the if() pointcut - only within an @Pointcut expression. The if() must not contain any - body. The annotated @Pointcut method must then be of the form public static boolean - and can use formal bindings as usual. - Extra implicit arguments of type JoinPoint, JoinPoint.StaticPart and JoinPoint.EnclosingStaticPart can also be used - (this is not permitted for regular annotated pointcuts not using the if() form). - - - - The special forms if(true) and if(false) can be used in a more - general way and don't imply that the pointcut method must have a body. - You can thus write @Before("somePoincut() && if(false)"). - - - + + It is thus possible with the annotation style to use the + if() + pointcut + only within an + @Pointcut + expression. The + if() + must not contain any + body. The annotated + @Pointcut + method must then be of the form + public static boolean + and can use formal bindings as usual. + Extra + implicit + arguments of type JoinPoint, JoinPoint.StaticPart and JoinPoint.EnclosingStaticPart can also be used + (this is not permitted for regular annotated pointcuts not using the + if() + form). + + + + The special forms + if(true) + and + if(false) + can be used in a more + general way and don't imply that the pointcut method must have a body. + You can thus write + @Before("somePoincut() && if(false)") + . + + + @@ -311,38 +354,41 @@ Advice 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 thisJoinPoint - and its siblings are handled in the body of advice and discuss the - treatment of - proceed in around advice. + and its siblings are handled in the body of advice and discuss the + treatment of + proceed + in around advice. 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 Before, After, AfterReturning, - AfterThrowing, or - Around annotations. Except in - the case of around advice, the method should return void. The method should - be declared public. + AfterThrowing, + or + Around + annotations. Except in + the case of around advice, the method should return void. The method should + be declared public. 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). + 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). The following example shows a simple before advice declaration in - both styles: + both styles: - - is equivalent to... + is equivalent to... - + is equivalent to... + + @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") + public void callFromFoo() { + System.out.println("Call from Foo"); + } + ]]> + + --> If the advice body needs to know which particular - Foo instance - is making the call, just add a parameter to the advice declaration. + Foo + instance + is making the call, just add a parameter to the advice declaration. - can be written as: + can be written as: If the advice body needs access to - thisJoinPoint, - thisJoinPointStaticPart, - thisEnclosingJoinPointStaticPart then these need to - be declared as additional method parameters when using the annotation - style. + thisJoinPoint + , + thisJoinPointStaticPart + , + thisEnclosingJoinPointStaticPart + then these need to + be declared as additional method parameters when using the annotation + style. - - is equivalent to... + + is equivalent to... - + Advice that needs all three variables would be declared: - JoinPoint.EnclosingStaticPart is a new (empty) sub-interface - of - JoinPoint.StaticPart which allows the AspectJ weaver to - distinguish based on type which of - thisJoinPointStaticPart and - thisEnclosingJoinPointStaticPart should be passed in a given - parameter position. + JoinPoint.EnclosingStaticPart + is a new (empty) sub-interface + of + JoinPoint.StaticPart + which allows the AspectJ weaver to + distinguish based on type which of + thisJoinPointStaticPart + and + thisEnclosingJoinPointStaticPart + should be passed in a given + parameter position. - After advice declarations take exactly the same form - as - Before, as do the forms of + After + advice declarations take exactly the same form + as + Before + , as do the forms of AfterReturning - and - AfterThrowing that do not expose the return type or - thrown exception respectively. + and + AfterThrowing + that do not expose the return type or + thrown exception respectively. - 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: - is equivalent to... + is equivalent to... (Note the use of the "pointcut=" prefix in front of the pointcut - expression in the returning case). + expression in the returning case). After throwing advice works in a similar fashion, using the - throwing attribute when needing to expose a - thrown exception. + throwing + attribute when needing to expose a + thrown exception. For around advice, we have to tackle the problem of - proceed. - 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 - proceed inside a method body: + proceed + . + 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 + proceed + inside a method body: will result in a "No such method" compilation error. For this - reason AspectJ 5 defines a new sub-interface of - JoinPoint, - ProceedingJoinPoint. + reason AspectJ 5 defines a new sub-interface of + JoinPoint + , + ProceedingJoinPoint + . - is equivalent to: + is equivalent to: - -Note that the ProceedingJoinPoint does not need to be passed to the proceed(..) arguments. - + Note that the ProceedingJoinPoint does not need to be passed to the proceed(..) arguments. + @@ -573,20 +632,19 @@ Inter-type Declarations - The features described in this section will not be supported until the - AspectJ 5 M4 milestone build. - - 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. - Consider the following aspect: + Consider the following aspect: - This declares an interface - Moody, 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 - getMoody, the type of + This declares an interface + Moody + , 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 + getMoody + , the type of this - is - Moody (the target type of the inter-type declaration). + is + Moody + (the target type of the inter-type declaration). 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 @@ ]]> - This is very similar to the mixin mechanism supported by AspectWerkz. The - effect of the - @DeclareParents 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 - this 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 + @DeclareParents + 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 + this + has access + to the exact same set of members as in the code style example. + + + + 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. + + + + It is important to remember that the @DeclareParents annotated aspect' field that serves as a host + for the inter-type declaration must be public static and initialized by some means. + The weaved code will indeed delegate calls to this field when f.e. invoking: + + + + + + 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. + + + + + If you need to only introduce a marker interface which defines no method - such as java.io.Serializable + it is possible to use the following syntax. + + + + Consider the following aspect: + + + + + Using the annotation style this aspect can be written: + + + + + + The @DeclareImplements annotation on the aspect' field dictates the type pattern + on which to introduce the marker interface. - The annotated class may only extend - Object, and may - only implement a single interface. The interface implemented by the class may - itself extend other interfaces. + + 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. @@ -672,17 +806,23 @@ Declare statements 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. - - Declare precedence and declare annotation - will - 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. + + + 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. + + + Declare precedence is + supported. For declare precedence, use the @DeclarePrecedence - annotation as in the following example: + annotation as in the following example: + 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. + 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. Note that the String must be a constant and not the result of the invocation - of a static method for example. + of a static method for example. aspectOf() and hasAspect() methods A central part of AspectJ's programming model is that aspects - written using the code style and compiled using ajc support - aspectOf and - hasAspect 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 + aspectOf + and + hasAspect + 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. 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 Aspects - utility class: + utility class: