Aspect models

AspectWerkz supports two models for Aspect components.

The model 1 is the historical ones. Aspects are defined in an XML file as an arrangement of java classes which are the Advices and the Introductions implementations and interfaces. The Pointcuts are defined in the XML file thru a specific syntax. The binding between pointcuts and Advices and/or Introductions defines on which class of the application to apply concern brought by the Advice and Introduction implementations.

The model 2 is based on MetaData (JSR-175). Aspect are pure java classes containing Advices as methods, Introductions as inner-class, and Pointcuts as field. Doclet in the Aspect class source file defines the binding between a Pointcut and Advices and/or Introductions. The Aspect class needs a post-compilation phase to incorporate the doclets in the aspect class file bytecode (this won't be needed with java 1.5). The XML is only declaring the Aspect classes.

To understand which model to use read the next section.

Model 1 - XML centric

The following sections detail the Model 1 XML centric approach where Advices and Introductions are classes and Aspect are described in an XML file.

  1. Advices
  2. Introductions
  3. Pointcuts
  4. Aspects
  5. Join points

Model 1 - Advices

The Advice class implements the advice concept, i.e. defines code that is executed when a join point is reached.

Implementation

There are currently four types of Advices supported:

  • AroundAdvice - is invoked "around" the join point. Can be used to intercept method invocations.


  • PreAdvice - is invoked before the join point. Can be used for advising fields or caller side pointcuts.


  • PostAdvice - is invoked after the join point. Can be used for advising fields or caller side pointcuts.


  • ThrowsAdvice - advises join points where an exception is thrown out of a method.

AroundAdvice

An AroundAdvice is implemented by extending the AroundAdvice class and implementing the abstract method Object execute(final JoinPoint jp).

Please note: An AroundAdvice can not be used with caller side or field pointcuts.

Here is a simple example of an AroundAdvice. (For more examples see the Examples section.)

It is in the method execute that the action takes place. The JoinPoint object that is passed to the method contains metadata of the current join point. To invoke the next advice in the chain (or the target method if there are no more advices) simply call joinPoint.proceed(). This method will return the result from the next advice (or the target method).

public class MyAroundAdvice extends AroundAdvice {
    public MyAroundAdvice() {
        super();
    }
    public Object execute(final JoinPoint joinPoint) throws Throwable {
        // do some stuff
        Object result = joinPoint.proceed();
        // do some more stuff
        return result;
    }
}


PreAdvice

A PreAdvice is implemented by extending either the abstract PreAdvice class and implementing the abstract method void execute(final JoinPoint jp). The PreAdvice class is being executed before the join point (that it has been applied to) has been is reached.

Here is a simple example of a PreAdvice advice. It is in the method execute that you can implement your logic. The JoinPoint object that is passed to the method contains metadata for the current join point. There is no need to call joinPoint.proceed() for either PreAdvices or PostAdvices.

public class MyPreAdvice extends PreAdvice {
    public MyPreAdvice() {
        super();
    }
    public void execute(final JoinPoint joinPoint) throws Throwable {
        // do some stuff
    }
}


PostAdvice

A PostAdvice is implemented by extending either the abstract PostAdvice class and implementing the abstract method void execute(final JoinPoint jp). The PreAdvice class is being executed before the join point (that it has been applied to) has been is reached.

Here is a simple example of a PostAdvice advice. It is in the method execute that you can implement your logic. The JoinPoint object that is passed to the method contains metadata for the current join point. There is no need to call joinPoint.proceed() for either PreAdvices or PostAdvices.

public class MyPostAdvice extends PostAdvice {
    public MyPostAdvice() {
        super();
    }
    public void execute(final JoinPoint joinPoint) throws Throwable {
        // do some stuff
    }
}


ThrowsAdvice

A ThrowsAdvice is implemented by extending the the ThrowsAdvice class and implementing the abstract method void execute(final JoinPoint jp). The ThrowsAdvice class is being executed after the join point (that it has been applied to) has been reached. I.e. when a specific exception has been thrown out of a specific method.

Here is a simple example of a ThrowsAdvice advice. It is in the method execute that you can implement your logic. The JoinPoint object that is passed to the method contains metadata of the current join point.

public class MyThrowsAdvice extends ThrowsAdvice {
    public MyThrowsAdvice() {
        super();
    }
    public void execute(final JoinPoint joinPoint) throws Throwable {
        Throwable cause = ((ThrowsJoinPoint)joinPoint).getException());
        // do some stuff
    }
}

Definition

Attributes

When defining the advices there are three attributes that needs to be specified:

  • name - for each advice you first have define the name of the advice. This name has to be unique and will work as a handle to the advice to be used when referencing the advice in the system.


  • advice - secondly you have to define the class name of the advice that the name attribute should be mapped to.


  • deployment-model - last we have an optional attribute specifying the deployment model to use. If no deployment model is defined the default perJVM (singleton) will be used. (For more information about the deployment model types available see the Deployment models section).


Here you also have the possibility to pass parameters to the advices. See the Passing parameters to advices section for a detailed description.

XML definition

<advice-def name="advices/caching"
            class="advices.CachingAdvice"
            deployment-model="perInstance">
    <param name="timeout" value="10"/>
</advice>

Model 1 - Introductions

The Introduction class implements the concept of Mixins/Open Classes. I.e. an Introduction makes it possible to extend a class with a new interface and/or a new implementation (methods and fields).

Implementation

Both the interface and the implementation extensions are just regular Java interfaces and classes. There is no need to have them implement a specific interface or extend a certain class. All you have to do is define them. The only rules are that the introduced implementation has to implement the introduced interface and have a default no-argument constructor.

When defining an interface introduction you only have to specify the interface, but when introducing a new implementation to a class, you must specifiy both the implementation class a matching interface. This is needed since if you don't specify an interface that the client can cast the target object to, the introduced implementation will not be accessible.

Note: if you add more than one Introduction to a target class then you have to make shure that the names of the methods does not collide (or you will get strange results).

Definition

Attributes

When defining the introductions there are four attributes that needs to be specified:

  • name - each introduction needs to have a unique name that will work as a handle to the advice to be used when referencing the introduction in the system.


  • interface - this attribute specifies the full name of the interface class to use.


  • implementation - this attribute specifies the full name of the implementation class to use. (Is skipped when we are defining an interface introduction).


  • deployment-model - is an optional attribute specifying the deployment model to use. If no deployment model is defined the default perJVM (singleton) will be used. (For more information about the deployment model types available see the Deployment models section).

XML definition

<introduction-def name="java/io/Serializable"
                  interface="java.io.Serializable"/>

<introduction-def name="mixins/Mixin"
                  interface="mixins.Mixin"
                  implementation="mixins.MixinImpl"
                  deployment-model="perThread"/>

(These examples only shows how to define the Introduction, for examples how to add them see the Aspects section.)

Model 1 - Pointcuts

The Pointcut class implements the pointcut concept. Pointcuts selects join points and values at those points, i.e. selects well-defined points in the program flow.

Implementation

There are currently four different types of pointcuts supported:

  • MethodPointcut - picks out join points defining method execution. Valid advice for this pointcut is AroundAdvice.


  • FieldPointcut - picks out join points defining field access or modification. Valid advices for this pointcut are PreAdvice and PostAdvice.


  • ThrowsPointcut - picks out join points definining where an exception is thrown out of a method. Valid advice for this pointcut is ThrowsAdvice.


  • CallerSidePointcut - picks out join points defining method invocation on the caller side. Valid advices for this pointcut are PreAdvice and PostAdvice.


  • CFlowPointcut - picks out join points defining a control flow (cflow). This pointcut can only be used on conjunction with other pointcuts.

Definition

Attributes

When defining the pointcuts there are three attributes that needs to be specified:

  • name - specifies the name of the pointcut. Needs to be a unique name throughout the aspect definintion.

    Caution: names must only consist of these characters: [A-Z], [a-z], [0-9] and the characters $ and _ (not for example - or /).


  • type - specifies the type of the pointcut. Valid types are (all lowercase is also valid):
    • method
    • setField
    • getField
    • throws
    • callerSide
    • cflow


  • pattern - specifies the pattern for the pointcut. This is the pattern that picks out the join points that should be included in the pointcut.

    For the ThrowsPointcut the pattern is defined like this: methodPattern#fullyQualifiedNameOfException.

    For the CallerSidePointcut the pattern is defined like this: callerSideClassPattern->calleeSideMethodPattern.

    See the Join point selection pattern language section for a detailed description on how these patterns work and are used. `


XML definition

<aspect ...>
    <pointcut-def name="pc1" type="method" pattern="* foo.Bar.method(..)"/>
    <pointcut-def name="pc2" type="setField" pattern="* foo.Bar.m_field"/>
    <pointcut-def name="pc3" type="getField" pattern="* foo.Bar.m_field"/>
    <pointcut-def name="pc4" type="throws" pattern="* foo.Bar.method(..)#java.lang.Exception"/>
    <pointcut-def name="pc5" type="callerSide" pattern="foo.Caller->String foo.Callee.method()"/>
    <pointcut-def name="pc6" type="cflow" pattern="* Transaction.begin(..)"/>
    ...
</aspect>

Model 1 - Aspects

The Aspect class implements the aspect concept. Aspects are AspectWerkz's unit of modularity for crosscutting concerns. They are defined in terms of pointcuts, advices and introductions.

Definition

Abstract aspects - aspect inheritance

You have the possibility of defining abstract aspects that you can reuse by letting aspects inherit the the abstract aspect using the extends attribute. Aspect inheritance works pretty much like regular class inheritance. An abstract aspect is defined using the abstract-aspect element.

Attributes

When defining the aspects there is first one attribute that needs to be specified:

  • name - specifies a unique name for the aspect.


  • extends - specifies the abstract aspect that the aspect extends (optional).


Adding the pointcuts definitions

In the aspect definition you put the pointcut definitions (see the Pointcuts section).

Adding the introductions

Then you specify the introductions that you want to define in this aspect. This is done using the bind-introduction element. You can also use the introduction element although it is deprecated and therefore not recommended.

This element has an attribute class where you define the pattern for the classes that you want to be applied by this/these introductions. Within this element you define the references to the introductions. Using the introduction-ref element: <introduction-ref name="nameOfIntroduction"/>

Adding the advices

You also define which advices should be applied to which pointcuts. This is done using the bind-advice element. You can also use the advice element although it is deprecated and therefore not recommended.

The advice element has an attribute called expression (pointcut works fine as well) in which you can define an expression based on the names of the pointcuts you have defined for this aspect.

This expression can be any (almost) kind of algebraic expression. The only difference is that you have to use OR instead of || and AND instead of && (lowercase works fine as well). AND is needed because it is cumbersome to write && in XML (needs to be escaped) and OR is used to make it coherent;

Here you also define if the pointcut/expression should be a part of a control flow using the cflow attribute. The cflow is defined using its pointcut name.

XML definition

<abstract-aspect name="MyAbstractAspect">
    <bind-advice cflow="facadeCalls" pointcut="setters AND !getters">
        <advices-ref name="log_and_cache"/>
    </bind-advice>

    <bind-advice pointcut="persistentFields">
        <advice-ref name="persistent"/>
    </bind-advice>
</aspect>

<aspect name="MyAspect" extends="MyAbstractAspect">
    <bind-introduction class="domain.*">
        <introduction-ref name="serializable"/>
        <introduction-ref name="mixin"/>
    </bind-introduction>

    <pointcut-def name="facadeCalls" type="cflow" pattern="* *..facade.*.*(..)"/>
    <pointcut-def name="setters" type="method" pattern="String domain.*.set*(..)"/>
    <pointcut-def name="getters" type="method" pattern="String domain.*.get*(..)"/>
    <pointcut-def name="persistentFields" type="setField" pattern="* domain.*.*">
</aspect>

Model 1 - Join points

The JoinPoint class implements the join point concept, i.e. a well-defined point in the program flow. A JoinPoint is picked out by a Pointcut.

Implementation

There are four different types of join points:

  • MethodJoinPoint


  • FieldJoinPoint


  • ThrowsJoinPoint


  • CallerSideJoinPoint

You only have to deal with the different types of join points when you in your Advice need to cast the JoinPoint object to a specific type to be able to retrieve meta-data from this specific join point. See the JavaDoc for more information on what information is available.

Model 2 - Self-defined Aspects

The following sections outlines the Model 2 - Self-defined Aspects approach, where Aspects are classes whose methods are Advices, fields are Pointcuts and inner classes are Introductions with metadata markers (JSR-175 ready).

You should be familiar with the vocabulary of AOP and the AspectWerkz implementation as explained in the model 1 section.

  1. Aspects
  2. Pointcuts
  3. Advices
  4. Introductions
  5. Metadata reference
  6. Aspect compilation

Model 2 - Aspects

The Aspect class implements the aspect concept. Aspects are AspectWerkz's unit of modularity for crosscutting concerns. They are defined in terms of pointcuts, advices and introductions.

Implementation

Aspect

Aspect are regular java classes. They must satisfy two criterias:

  1. extends org.codehaus.aspectwerkz.attribdef.aspect.Aspect whether directly or indirectly by extending another subclass.


  2. have a @Aspect metadata marker at the class level i.e. in the class javadoc section. Here is also where you specify the deployment model of the Aspect.
An aspect implementation must thus extend the Aspect in its object hierarchy. The Aspect class provides some useful operations to access runtime information:
  • ___AW_getTargetClass() to access the target class
  • See JavaDoc of Aspect class for a complete list.

Abstract aspects - aspect inheritance

Since the Aspects are pure java classes in this model, you have the possibility of defining abstract aspects that you can reuse by implementing another aspect that inherits the abstract aspect.

Aspect inheritance is exactly regular class inheritance. An abstract aspect is defined using the abstract keyword as a regular abstract class and is inherited using the extends keyword.

Metadata

When defining the aspect, the deployment model is specified as metadata argument of the metadata tag @Aspect. The current implementation uses a doclet syntax. AspectWerkz will support JSR-175 syntax as well, as soon as it is available.

@Aspect class level metadata has

  1. an optional anonymous parameter which specifies the deployment model. The default is perJVM if not specified.


  2. an optional name= named parameter which specify the name of the aspect. The default is the aspect class name if not specified.


  • @Aspect perJVM - deploys as perJVM. This is the default if only @Aspect is specified.


  • @Aspect perClass - deploys as perClass.


  • @Aspect perInstance - deploys as perInstance.


  • @Aspect perThread - deploys as perThread.


Adding the pointcuts definitions

In the aspect class you put the pointcut definitions as fields of the type org.codehaus.aspectwerkz.attribdef.Pointcut along with metadata attributes which specifies the type of pointcut (execution, call, set, get, cflow or throws). See Pointcuts section.

In the aspect class you specify the introduction to add as field for pure interface introduction (marker interface with no required method) or as public inner-class for interface and implementation introduction.

Pure interface introduction are added by adding a field to the aspect. The field type has to be the interface that you want to introduce. The @Introduce metadata is then used to specify the pattern matching the classes you want the introduction to be applied to. See Introductions section.

Interface introduction with implementation, also known as mixins, are added by adding a public inner-class to the aspect class. The inner-class is then the default introduction/mixin implementation. It can extend any class you want, just like any other regular java class. The @Implements metadata specifies the pattern matching the classes you want the introduction/mixin to be applied to. The interface(s) introduced can be whether be set explicitly by letting the inner-class implement the interface(s), whether implicitly by inheriting another class which is itself implementing the interface(s). This can be handy when distributing reusable aspects. See Introductions section.

Adding the advices

In the aspect class the advices are regular methods conforming to the public Object <name of method>(JoinPoint joinPoint) throws Throwable signature. The type of the advice, either Around, Before or After, is specified using metadata for the method along with the method or field pattern or pattern expression to which it the advice should be bound. See Advices section

This expression can be any (almost) kind of algebraic expression. The operators ||, OR, &&, AND are supported.

Here you also define if the pointcut/expression should be a part of a control flow using an algebraic AND expression mixing one or more pointcut names with one or more poincut names of type CFlow i.e. whose matching Pointcut fields are marked with @CFlow metadata.

Definition

XML definition

The XML definition is just declaring which concrete aspects to use. See dedicated section for complete definition issue documentation.

<use-aspect class="package.NonAbstractAspect"/>

Source sample

The following source sample gives the main ideas of the self-defined Aspect. Please remember that the metadata markers are inserted in the bytecode through a post-compilation step which won't be needed under java 1.5.

/**
 * @Aspect perInstance name=SomeNameForMyAspect
 */
public class MyAspect extends Aspect {

    /**
     * @Implements com.mypackage.*
     */
    MarkerInterface anIntroduction;

    /**
     * @Execution * com.mypackage.Target.*(..)
     */
    Pointcut pc1;

    /**
     * @Around pc1
     */
    public Object advice1(final JoinPoint joinPoint) throws Throwable {
        // do some stuff
        Object result = joinPoint.proceed();
        // do some other stuff
        return result;
    }

    /**
     * @Introduce com.mypackage.*
     */
    public class OtherIntroduction extends SuperMixin implements ContractualInterface {
        ... // introduced methods and fields
    }
}

Model 2 - Pointcuts

The Pointcut class implements the pointcut concept. A Pointcut picks out join points, i.e. selects well-defined points in the program flow.

Implementation

The Pointcuts are implemented as fields in the Aspect class and they have to follow the following requirements:

  1. the field is of type org.codehaus.aspectwerkz.attribdef.Pointcut and should be declared in the aspect class or hierarchy.


  2. the metadata markers at the field level allows to define the type of Pointcut (see model 1 section).


The name of the pointcut is the field name.

The following types of pointcuts are currently supported and type is specified as metadata at the field level:
  • @Execution <methodPattern> - picks out join points defining method execution. Valid advice method metadata for this pointcut is @Around


  • @Call <callerSidePattern> - picks out join points defining method invocation on the caller side. Valid advice method metadata for this pointcut are @Before and @After.


  • @Class <classPattern> - picks out class names. To be used with mixin @Implements and @Introduce metadata.


  • @Set <fieldPattern> - picks out join points defining field modification. Valid advice method metadata for this pointcut are @Before and @After.


  • @Get <fieldPattern> - picks out join points defining field access. Valid advice method metadata for this pointcut are @Before and @After.


  • @Throws <throwsPattern> - picks out join points definining where an exception is thrown out of a method. Valid advice method metadata for this pointcut is @Around.


  • @CFlow <methodPattern> - picks out join points defining a control flow (cflow). This pointcut can only be used on conjunction with other pointcut types in an algebraic AND expression.

    /**
     * @Execution * com.package..*.*(..)
     */
    Poincut allMethods;

    /**
     * @Set * com.package.Constants.*
     */
    Pointcut allConstantAccess;

These metadata attributes are followed by the pattern. The exact syntax depends of the type of the Advice itself. This is the pattern that picks out the join points that should be included in the pointcut.

For the @Throws the pattern is defined like this: methodPattern#fullyQualifiedNameOfException.

For the @Call the pattern is defined like this: callerSideClassPattern->calleeSideMethodPattern.

See the Join point selection pattern language section for a detailed description on how these patterns work and are used.

Model 2 - Advices

The Advices are implemented as regular methods in the Aspect class with the following requirements:

  1. the signature is public Object <name of method>(JoinPoint joinPoint) throws Throwable (the public modifier is not mandatory, choose according to your needs).


  2. the method has a metadata that specifies the advice type and the matching joinpoints through a pointcut expression. The matching joinpoints are whether defined as an anonymous pointcut (and not a as a field) whether as an algebraic expression composed by other poincuts, whose type matches the advice type.


Implementation

The supported types of Advices are the following. Each type is a metadata marker at the method level with:

  1. a mandatory anonymous parameter to specify the expression for matching joinpoints.
  2. an optional name= parameter which specify the advice name. Defaults to the <aspect class name>.<method name> if not specified.
  • @Around <expression> - is invoked "around" the join point. Can be used to intercept method invocations on the 'callee' side.


  • @Before <expression> - is invoked before the join point. Can be used for advising fields or method invocations on the 'caller' side.


  • @After <expression> - is invoked after the join point. Can be used for advising fields or method invocations on the 'caller' side.


  • @Throws <expression> - advises join points where an exception is thrown out of a method.

Here is a simple example of an AroundAdvice. (For more examples see the Examples section.)

It is in the method execute that the action takes place. The JoinPoint object that is passed to the method contains metadata of the current join point. To invoke the next advice in the chain (or the target method if there are no more advices) simply call joinPoint.proceed(). This method will return the result from the next advice (or the target method). It is possible to cast the JoinPoint to the JointPoint subclass matching the advice type used (MethodJoinPoint, FieldJoinPoint, ThrowsJoinPoint and subclasses).

    /**
     * Non anonymous expression (pc1 and pc2 are fields of type Pointcut with metadata).
     * @Around pc1 && pc2
     */
    public Object myAroundAdvice(JoinPoint joinPoint) throws Throwable {
        // do some stuff
        Object result = joinPoint.proceed();
        // do some more stuff
        return result;
    }

    /**
     * Anonymous pointcut.
     * @Around * com.package.Target.*(..)
     */
    public Object myAroundAdvice(JoinPoint joinPoint) throws Throwable {
        // do some stuff
        Object result = joinPoint.proceed();
        // do some more stuff
        return result;
    }
}

Model 2 - Introductions

The Introduction class implements the concept of Mixins or Open Classes. I.e. an Introduction makes it possible to extend a class with a new interface and/or a new implementation (methods and fields).

In model 2, introductions are defined as

  • Fields of the aspect class whose type is the interface to introduce.

    Use if the interface does not require any implementation (marker interface).

    Fields are marked with metadata @Implements <classPattern>.


  • Public inner class of the aspect class.

    The inner class declares to implement the interface(s) to introduce and effectively implements it. The inner class is marked with metadata @Introduce <classPattern>.

Pure Interface introduction

Interface introductions (introduction of marker interfaces) are defined as fields in the aspect class. The type of the field is the interface to introduce.

The field is marked with metadata @Implements <classPattern> to specify to which classes the introduction applies.

The name of the introduction is the field name.

When using abstract aspects or aspect inheritance, the aspect's super class can define interface introductions without specifying a @Implements <classPattern> metadata. The concrete aspect should thus override the fields and specify the metadata defining to which classes the introduction applies.

/**
 * @Aspect
 */
public MyAspect extends Aspect {

    /**
     * @Implements com.package.*
     */
    protected Serializable introduction1;

    /**
     * @Implements com.package.*
     */
    public OtherMarkerInterface introduction2;
 }
                    

Implementation introduction

Implementation introductions (interface with concrete implementation), also known as mixins, are defined as public inner class of the aspect class. It is mandatory for the inner class to be accessible with a no-arg constructor, thus to be public or to explicitly have a no-arg constructor. The inner class implements the interface(s) to introduce on the target class.

The inner class is marked with metadata @Introduce <classPattern> to specify to which classes the introduction applies.

The @Introduce attribute accepts an optional deploymentModel= parameter to specify the introduction deployment model. If not specified the aspect deployment model applies. See deployment model section.

The name of the introduction is the fully qualified inner class name e.g. <aspectClassName>$<innerClassName>.

When using abstract aspects or aspect inheritance, the aspect's super class can define introductions without specifying a @Introduce <classPattern> metadata. The concrete aspect should thus declare an inner class that extends the super class aspect one's and specify thru metadata to which classes the introduction applies.

/**
 * @Aspect
 */
public MyAspect extends Aspect {

    /**
     * Anonymous pointcut.
     *
     * @Introduce com.package.*
     */
    public class MyIntroduction extends SuperIntroduction implements ToBeIntroduced {
        // introduced methods implementation
        ...
    }

    /**
     * @Class com.package.Foo
     */
    Pointcut pc1;

    /**
     * Named pointcut(s) in expression.
     *
     * @Introduce pc1
     */
    public class AnotherIntroduction implements AnotherToBeIntroduced {
        // introduced methods implementation
        ...
    }
 }
                    

Implementation swapping

It is possible to replace the introduction implementation at runtime using a call like

SystemLoader.getSystem("systemId").getMixin("test.attribdef.aspect.IntroductionTestAspect$MyImpl").
    ___AW_swapImplementation("test.attribdef.aspect.IntroductionTestAspectMyImplReplacement");
                    

The swapped implementation must implement the introduced interfaces, but can be an autonomous class or an aspect inner class. Only the default introduced implementation must be an inner class.

Model 2 - Metadata reference

This section references all metadata used in the model 2 - Self defined aspect model.

metalevelcomponentanonymous parameterparameter(s)
[O:defaultValue] for optional parameter with default value
@AspectclassAspectperJVM | perClass | perInstance | perThread [O:perJVM]name [0:<aspectClassName>]
@ImplementsfieldInterface Introduction<classPattern>
@Introduceinner class, class levelImplementation Introduction<classPattern>deploymentModel=perJVM | perClass | perInstance | perThread [O: aspect'one]
@ClassPointcut fieldPointcut, class selection<classPattern>
@ExecutionPointcut fieldPointcut, method execution<methodPattern>
@CallPointcut fieldPointcut, method call<callerSidePattern>
@Set / @GetPointcut fieldPointcut, field modification / access<fieldPattern>
@ThrowsPointcut fieldPointcut, exception throwned out<throwsPattern>
@CFlowPointcut fieldPointcut, in cflow of<methodPattern>
@AroundMethodAdvice for @Around, @Throws<expression>name [0:<aspectClassName>.<methodName>
@BeforeMethodAdvice for @Call, @Set, @Get<expression>name [0:<aspectClassName>.<methodName>
@AfterMethodAdvice for @Call, @Set, @Get<expression>name [0:<aspectClassName>.<methodName>
@ThrowsMethodAdvice for @Throws<expression>name [0:<aspectClassName>.<methodName>
@Attribute.<name>anycustom runtime accessible attribute

Model 2 - Aspect post-compilation

The model 2 - self-defined Aspects have to be post-compiled to incorporate the metadata into the class file bytecode. This post-compilation step will not be needed with java 1.5 and JSR-175. For now you need to first compile the aspect classes with javac compiler and then post compile the .class files with the aspect source code as input.

See specific part

Choosing a model

The model 1 - XML centric model allows to define the pointcut expressions in an external file. It can be used to provide aspects that needs to be tuned without an extra development phase (apart from editing an XML file). This model leads to a more exploded aspect since several classes are needed (one per Advice). The main disadvantage with this approach is that the implementation is separated from the definition which makes the code harder to refactor, maintain and reuse.

The model 2 - Self-defined aspect allows you to have truly self-contained aspect components. Those are easier to maintain, refactor and reuse as well as build libraries upon. The drawback is that it requires an additional post-compilation step (until java 1.5) to annotate them with the metadata.