| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>The AspectJTM Programming Guide</title><link rel="stylesheet" href="aspectj-docs.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.44"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" id="d0e1"><div class="titlepage"><div><h1 class="title"><a name="d0e1"></a>The AspectJ<sup>TM</sup> Programming Guide</h1></div><div><h3 class="author">the AspectJ Team</h3></div><div><div class="legalnotice"><p> |
| Copyright (c) 1998-2001 Xerox Corporation, |
| 2002-2003 Palo Alto Research Center, Incorporated. |
| All rights reserved. |
| </p></div></div><div><div class="abstract"><p><a name="d0e15"></a><b>Abstract</b></p><p> |
| This programming guide describes the AspectJ language. A |
| companion guide describes the tools which are part of the |
| AspectJ development environment. |
| </p><p> |
| If you are completely new to AspectJ, you should first read |
| <a href="#starting">Getting Started with AspectJ</a> for a broad overview of programming |
| in AspectJ. If you are already familiar with AspectJ, but want a deeper |
| understanding, you should read <a href="#language">The AspectJ Language</a> and |
| look at the examples in the chapter. If you want a more formal |
| definition of AspectJ, you should read <a href="#semantics">Semantics</a>. |
| </p></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#preface">Preface</a></dt><dt>1. <a href="#starting">Getting Started with AspectJ</a></dt><dd><dl><dt><a href="#starting-intro">Introduction</a></dt><dt><a href="#starting-aspectj">Introduction to AspectJ</a></dt><dd><dl><dt><a href="#the-dynamic-join-point-model">The Dynamic Join Point Model</a></dt><dt><a href="#pointcuts">Pointcuts</a></dt><dt><a href="#advice">Advice</a></dt><dt><a href="#inter-type-declarations">Inter-type declarations</a></dt><dt><a href="#aspects">Aspects</a></dt></dl></dd><dt><a href="#starting-development">Development Aspects</a></dt><dd><dl><dt><a href="#tracing">Tracing</a></dt><dt><a href="#profiling-and-logging">Profiling and Logging</a></dt><dt><a href="#pre-and-post-conditions">Pre- and Post-Conditions</a></dt><dt><a href="#contract-enforcement">Contract Enforcement</a></dt><dt><a href="#configuration-management">Configuration Management</a></dt></dl></dd><dt><a href="#starting-production">Production Aspects</a></dt><dd><dl><dt><a href="#change-monitoring">Change Monitoring</a></dt><dt><a href="#context-passing">Context Passing</a></dt><dt><a href="#starting-production-consistentBehavior">Providing Consistent Behavior</a></dt></dl></dd><dt><a href="#starting-conclusion">Conclusion</a></dt></dl></dd><dt>2. <a href="#language">The AspectJ Language</a></dt><dd><dl><dt><a href="#language-intro">Introduction</a></dt><dt><a href="#language-anatomy">The Anatomy of an Aspect</a></dt><dd><dl><dt><a href="#an-example-aspect">An Example Aspect</a></dt><dt><a href="#pointcuts">Pointcuts</a></dt><dt><a href="#advice">Advice</a></dt></dl></dd><dt><a href="#language-joinPoints">Join Points and Pointcuts</a></dt><dd><dl><dt><a href="#some-example-pointcuts">Some Example Pointcuts</a></dt><dt><a href="#call-vs-execution">call vs. execution</a></dt><dt><a href="#pointcut-composition">Pointcut composition</a></dt><dt><a href="#pointcut-parameters">Pointcut Parameters</a></dt><dt><a href="#example">Example: <tt>HandleLiveness</tt></a></dt></dl></dd><dt><a href="#language-advice">Advice</a></dt><dt><a href="#language-interType">Inter-type declarations</a></dt><dd><dl><dt><a href="#inter-type-scope">Inter-type Scope</a></dt><dt><a href="#example-pointassertions">Example: <tt>PointAssertions</tt></a></dt></dl></dd><dt><a href="#language-thisJoinPoint">thisJoinPoint</a></dt></dl></dd><dt>3. <a href="#examples">Examples</a></dt><dd><dl><dt><a href="#examples-intro">Introduction</a></dt><dt><a href="#examples-howto">Obtaining, Compiling and Running the Examples</a></dt><dt><a href="#examples-basic">Basic Techniques</a></dt><dd><dl><dt><a href="#examples-joinPoints">Join Points and <tt>thisJoinPoint</tt></a></dt><dt><a href="#examples-roles">Roles and Views</a></dt></dl></dd><dt><a href="#examples-development">Development Aspects</a></dt><dd><dl><dt><a href="#tracing-using-aspects">Tracing using aspects</a></dt></dl></dd><dt><a href="#examples-production">Production Aspects</a></dt><dd><dl><dt><a href="#a-bean-aspect">A Bean Aspect</a></dt><dt><a href="#the-subject-observer-protocol">The Subject/Observer Protocol</a></dt><dt><a href="#a-simple-telecom-simulation">A Simple Telecom Simulation</a></dt></dl></dd><dt><a href="#examples-reusable">Reusable Aspects</a></dt><dd><dl><dt><a href="#tracing-using-aspects-revisited">Tracing using Aspects, Revisited</a></dt></dl></dd></dl></dd><dt>4. <a href="#idioms">Idioms</a></dt><dd><dl><dt><a href="#idioms-intro">Introduction</a></dt></dl></dd><dt>5. <a href="#pitfalls">Pitfalls</a></dt><dd><dl><dt><a href="#pitfalls-intro">Introduction</a></dt><dt><a href="#pitfalls-infiniteLoops">Infinite loops</a></dt></dl></dd><dt>A. <a href="#quick">AspectJ Quick Reference</a></dt><dd><dl><dt><a href="#quick-pointcuts">Pointcuts</a></dt><dt><a href="#quick-typePatterns">Type Patterns</a></dt><dt><a href="#quick-advice">Advice</a></dt><dt><a href="#quick-interType">Inter-type member declarations</a></dt><dt><a href="#quick-other">Other declarations</a></dt><dt><a href="#quick-aspectAssociations">Aspects</a></dt></dl></dd><dt>B. <a href="#semantics">Language Semantics</a></dt><dd><dl><dt><a href="#semantics-intro">Introduction</a></dt><dt><a href="#semantics-joinPoints">Join Points</a></dt><dt><a href="#semantics-pointcuts">Pointcuts</a></dt><dd><dl><dt><a href="#pointcut-definition">Pointcut definition</a></dt><dt><a href="#context-exposure">Context exposure</a></dt><dt><a href="#primitive-pointcuts">Primitive pointcuts</a></dt><dt><a href="#signatures">Signatures</a></dt><dt><a href="#matching">Matching</a></dt><dt><a href="#type-patterns">Type patterns</a></dt><dt><a href="#pattern-summary">Pattern Summary</a></dt></dl></dd><dt><a href="#semantics-advice">Advice</a></dt><dd><dl><dt><a href="#advice-modifiers">Advice modifiers</a></dt><dt><a href="#advice-and-checked-exceptions">Advice and checked exceptions</a></dt><dt><a href="#advice-precedence">Advice precedence</a></dt><dt><a href="#reflective-access-to-the-join-point">Reflective access to the join point</a></dt></dl></dd><dt><a href="#semantics-declare">Static crosscutting</a></dt><dd><dl><dt><a href="#inter-type-member-declarations">Inter-type member declarations</a></dt><dt><a href="#access-modifiers">Access modifiers</a></dt><dt><a href="#conflicts">Conflicts</a></dt><dt><a href="#extension-and-implementation">Extension and Implementation</a></dt><dt><a href="#interfaces-with-members">Interfaces with members</a></dt><dt><a href="#warnings-and-errors">Warnings and Errors</a></dt><dt><a href="#softened-exceptions">Softened exceptions</a></dt><dt><a href="#advice-precedence">Advice Precedence</a></dt><dt><a href="#statically-determinable-pointcuts">Statically determinable pointcuts</a></dt></dl></dd><dt><a href="#semantics-aspects">Aspects</a></dt><dd><dl><dt><a href="#aspect-declaration">Aspect Declaration</a></dt><dt><a href="#aspect-extension">Aspect Extension</a></dt><dt><a href="#aspect-instantiation">Aspect instantiation</a></dt><dt><a href="#aspect-privilege">Aspect privilege</a></dt></dl></dd></dl></dd><dt>C. <a href="#implementation">Implementation Notes</a></dt><dd><dl><dt><a href="#d0e7185">Compiler Notes</a></dt><dt><a href="#d0e7259">Bytecode Notes</a></dt><dd><dl><dt><a href="#the-class-expression-and-string">The .class expression and String +</a></dt><dt><a href="#the-handler-join-point">The Handler join point</a></dt><dt><a href="#initializers-and-inter-type-constructors">Initializers and Inter-type Constructors</a></dt></dl></dd><dt><a href="#d0e7365">Summary of implementation requirements</a></dt></dl></dd></dl></div><div id="preface" class="preface"><div class="titlepage"><div><h2 class="title"><a name="preface"></a>Preface</h2></div></div><p> |
| This programming guide does three things. It |
| |
| <div class="itemizedlist"><ul compact><li><p><a name="d0e32"></a>introduces the AspectJ language</p></li><li><p><a name="d0e35"></a> |
| defines each of AspectJ's constructs and their semantics, and |
| </p></li><li><p><a name="d0e38"></a> |
| provides examples of their use. |
| </p></li></ul></div> |
| |
| It includes appendices that give a reference to the syntax of AspectJ, |
| a more formal description of AspectJ's semantics, and a description of |
| notes about the AspectJ implementation. |
| </p><p> |
| The first section, <a href="#starting">Getting Started with AspectJ</a>, provides a gentle |
| overview of writing AspectJ programs. It also shows how one can |
| introduce AspectJ into an existing development effort in stages, |
| reducing the associated risk. You should read this section if this is |
| your first exposure to AspectJ and you want to get a sense of what |
| AspectJ is all about. |
| </p><p> |
| The second section, <a href="#language">The AspectJ Language</a>, covers the features of |
| the language in more detail, using code snippets as examples. All the |
| basics of the language is covered, and after reading this section, you |
| should be able to use the language correctly. |
| </p><p> |
| The next section, <a href="#examples">Examples</a>, comprises a set of |
| complete programs that not only show the features being used, but also |
| try to illustrate recommended practice. You should read this section |
| after you are familiar with the elements of AspectJ. |
| </p><p> |
| Finally, there are two short chapters, one on <a href="#idioms">Idioms</a> |
| and one on <a href="#pitfalls">Pitfalls</a>. |
| </p><p> |
| The back matter contains several appendices that cover a <a href="#quick">AspectJ Quick Reference</a> to the language's syntax, a more |
| in depth coverage of its <a href="#semantics">Semantics</a>, |
| and a description of the latitude enjoyed by its <a href="#implementation">Implementation Notes</a>. |
| </p></div><div class="chapter"><div class="titlepage"><div><h2 class="title"><a name="starting"></a>Chapter 1. Getting Started with AspectJ</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#starting-intro">Introduction</a></dt><dt><a href="#starting-aspectj">Introduction to AspectJ</a></dt><dd><dl><dt><a href="#the-dynamic-join-point-model">The Dynamic Join Point Model</a></dt><dt><a href="#pointcuts">Pointcuts</a></dt><dt><a href="#advice">Advice</a></dt><dt><a href="#inter-type-declarations">Inter-type declarations</a></dt><dt><a href="#aspects">Aspects</a></dt></dl></dd><dt><a href="#starting-development">Development Aspects</a></dt><dd><dl><dt><a href="#tracing">Tracing</a></dt><dt><a href="#profiling-and-logging">Profiling and Logging</a></dt><dt><a href="#pre-and-post-conditions">Pre- and Post-Conditions</a></dt><dt><a href="#contract-enforcement">Contract Enforcement</a></dt><dt><a href="#configuration-management">Configuration Management</a></dt></dl></dd><dt><a href="#starting-production">Production Aspects</a></dt><dd><dl><dt><a href="#change-monitoring">Change Monitoring</a></dt><dt><a href="#context-passing">Context Passing</a></dt><dt><a href="#starting-production-consistentBehavior">Providing Consistent Behavior</a></dt></dl></dd><dt><a href="#starting-conclusion">Conclusion</a></dt></dl></div><div class="sect1"><a name="starting-intro"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="starting-intro"></a>Introduction</h2></div></div><p> |
| Many software developers are attracted to the idea of aspect-oriented |
| programming (AOP) but unsure about how to begin using the |
| technology. They recognize the concept of crosscutting concerns, and |
| know that they have had problems with the implementation of such |
| concerns in the past. But there are many questions about how to adopt |
| AOP into the development process. Common questions include: |
| |
| <div class="itemizedlist"><ul compact><li><p><a name="d0e80"></a>Can I use aspects in my existing code?</p></li><li><p><a name="d0e83"></a> |
| What kinds of benefits can I expect to get from using aspects? |
| </p></li><li><p><a name="d0e86"></a>How do I find aspects in my programs?</p></li><li><p><a name="d0e89"></a>How steep is the learning curve for AOP?</p></li><li><p><a name="d0e92"></a>What are the risks of using this new technology?</p></li></ul></div> |
| </p><p> |
| This chapter addresses these questions in the context of AspectJ: a |
| general-purpose aspect-oriented extension to Java. A series of |
| abridged examples illustrate the kinds of aspects programmers may |
| want to implement using AspectJ and the benefits associated with |
| doing so. Readers who would like to understand the examples in more |
| detail, or who want to learn how to program examples like these, can |
| find more complete examples and supporting material linked from the |
| AspectJ web site ( <a href="http://eclipse.org/aspectj" target="_top">http://eclipse.org/aspectj</a> ). |
| </p><p> |
| A significant risk in adopting any new technology is going too far |
| too fast. Concern about this risk causes many organizations to be |
| conservative about adopting new technology. To address this issue, |
| the examples in this chapter are grouped into three broad categories, |
| with aspects that are easier to adopt into existing development |
| projects coming earlier in this chapter. The next section, <a href="#starting-aspectj">Introduction to AspectJ</a>, we present the core of AspectJ's |
| features, and in <a href="#starting-development">Development Aspects</a>, we present |
| aspects that facilitate tasks such as debugging, testing and |
| performance tuning of applications. And, in the section following, |
| <a href="#starting-production">Production Aspects</a>, we present aspects that |
| implement crosscutting functionality common in Java applications. We |
| will defer discussing a third category of aspects, reusable aspects, |
| until <a href="#language">The AspectJ Language</a>. |
| </p><p> |
| These categories are informal, and this ordering is not the only way |
| to adopt AspectJ. Some developers may want to use a production aspect |
| right away. But our experience with current AspectJ users suggests |
| that this is one ordering that allows developers to get experience |
| with (and benefit from) AOP technology quickly, while also minimizing |
| risk. |
| </p></div><div class="sect1"><a name="starting-aspectj"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="starting-aspectj"></a>Introduction to AspectJ</h2></div></div><p> |
| This section presents a brief introduction to the features of AspectJ |
| used later in this chapter. These features are at the core of the |
| language, but this is by no means a complete overview of AspectJ. |
| </p><p> |
| The features are presented using a simple figure editor system. A |
| <tt>Figure</tt> consists of a number of |
| <tt>FigureElements</tt>, which can be either |
| <tt>Point</tt>s or <tt>Line</tt>s. The |
| <tt>Figure</tt> class provides factory services. There |
| is also a <tt>Display</tt>. Most example programs later |
| in this chapter are based on this system as well. |
| </p><p> |
| <div class="mediaobject"><img src="figureUML.gif"><div class="caption"><p> |
| UML for the <tt>FigureEditor</tt> example |
| </p></div></div> |
| </p><p> |
| The motivation for AspectJ (and likewise for aspect-oriented |
| programming) is the realization that there are issues or concerns |
| that are not well captured by traditional programming |
| methodologies. Consider the problem of enforcing a security policy in |
| some application. By its nature, security cuts across many of the |
| natural units of modularity of the application. Moreover, the |
| security policy must be uniformly applied to any additions as the |
| application evolves. And the security policy that is being applied |
| might itself evolve. Capturing concerns like a security policy in a |
| disciplined way is difficult and error-prone in a traditional |
| programming language. |
| </p><p> |
| Concerns like security cut across the natural units of |
| modularity. For object-oriented programming languages, the natural |
| unit of modularity is the class. But in object-oriented programming |
| languages, crosscutting concerns are not easily turned into classes |
| precisely because they cut across classes, and so these aren't |
| reusable, they can't be refined or inherited, they are spread through |
| out the program in an undisciplined way, in short, they are difficult |
| to work with. |
| </p><p> |
| Aspect-oriented programming is a way of modularizing crosscutting |
| concerns much like object-oriented programming is a way of |
| modularizing common concerns. AspectJ is an implementation of |
| aspect-oriented programming for Java. |
| </p><p> |
| AspectJ adds to Java just one new concept, a join point -- and that's |
| really just a name for an existing Java concept. It adds to Java |
| only a few new constructs: pointcuts, advice, inter-type declarations |
| and aspects. Pointcuts and advice dynamically affect program flow, |
| inter-type declarations statically affects a program's class |
| hierarchy, and aspects encapsulate these new constructs. |
| </p><p> |
| A <span class="emphasis"><i>join point</i></span> is a well-defined point in the |
| program flow. A <span class="emphasis"><i>pointcut</i></span> picks out certain join |
| points and values at those points. A piece of |
| <span class="emphasis"><i>advice</i></span> is code that is executed when a join |
| point is reached. These are the dynamic parts of AspectJ. |
| </p><p> |
| AspectJ also has different kinds of <span class="emphasis"><i>inter-type |
| declarations</i></span> that allow the programmer to modify a |
| program's static structure, namely, the members of its classes and |
| the relationship between classes. |
| </p><p> |
| AspectJ's <span class="emphasis"><i>aspect</i></span> are the unit of modularity for |
| crosscutting concerns. They behave somewhat like Java classes, but |
| may also include pointcuts, advice and inter-type declarations. |
| </p><p> |
| In the sections immediately following, we are first going to look at |
| join points and how they compose into pointcuts. Then we will look at |
| advice, the code which is run when a pointcut is reached. We will see |
| how to combine pointcuts and advice into aspects, AspectJ's reusable, |
| inheritable unit of modularity. Lastly, we will look at how to use |
| inter-type declarations to deal with crosscutting concerns of a |
| program's class structure. |
| </p><div class="sect2"><a name="the-dynamic-join-point-model"></a><div class="titlepage"><div><h3 class="title"><a name="the-dynamic-join-point-model"></a>The Dynamic Join Point Model</h3></div></div><p> |
| A critical element in the design of any aspect-oriented language is |
| the join point model. The join point model provides the common |
| frame of reference that makes it possible to define the dynamic |
| structure of crosscutting concerns. This chapter describes |
| AspectJ's dynamic join points, in which join points are certain |
| well-defined points in the execution of the program. |
| </p><p> |
| AspectJ provides for many kinds of join points, but this chapter |
| discusses only one of them: method call join points. A method call |
| join point encompasses the actions of an object receiving a method |
| call. It includes all the actions that comprise a method call, |
| starting after all arguments are evaluated up to and including |
| return (either normally or by throwing an exception). |
| </p><p> |
| Each method call at runtime is a different join point, even if it |
| comes from the same call expression in the program. Many other |
| join points may run while a method call join point is executing -- |
| all the join points that happen while executing the method body, |
| and in those methods called from the body. We say that these join |
| points execute in the <span class="emphasis"><i>dynamic context</i></span> of the |
| original call join point. |
| </p></div><div class="sect2"><a name="pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="pointcuts"></a>Pointcuts</h3></div></div><p> |
| In AspectJ, <span class="emphasis"><i>pointcuts</i></span> pick out certain join |
| points in the program flow. For example, the pointcut |
| </p><pre class="programlisting"> |
| call(void Point.setX(int)) |
| </pre><p> |
| picks out each join point that is a call to a method that has the |
| signature <tt>void Point.setX(int)</tt> — that is, |
| <tt>Point</tt>'s void <tt>setX</tt> |
| method with a single <tt>int</tt> parameter. |
| </p><p> |
| A pointcut can be built out of other pointcuts with and, or, and |
| not (spelled <tt>&&</tt>, <tt>||</tt>, |
| and <tt>!</tt>). For example: |
| </p><pre class="programlisting"> |
| call(void Point.setX(int)) || |
| call(void Point.setY(int)) |
| </pre><p> |
| picks out each join point that is either a call to |
| <tt>setX</tt> or a call to <tt>setY</tt>. |
| </p><p> |
| Pointcuts can identify join points from many different types |
| — in other words, they can crosscut types. For example, |
| </p><pre class="programlisting"> |
| call(void FigureElement.setXY(int,int)) || |
| call(void Point.setX(int)) || |
| call(void Point.setY(int)) || |
| call(void Line.setP1(Point)) || |
| call(void Line.setP2(Point)); |
| </pre><p> |
| picks out each join point that is a call to one of five methods |
| (the first of which is an interface method, by the way). |
| </p><p> |
| In our example system, this pointcut captures all the join points |
| when a <tt>FigureElement</tt> moves. While this is a |
| useful way to specify this crosscutting concern, it is a bit of a |
| mouthful. So AspectJ allows programmers to define their own named |
| pointcuts with the <tt>pointcut</tt> form. So the |
| following declares a new, named pointcut: |
| </p><pre class="programlisting"> |
| pointcut move(): |
| call(void FigureElement.setXY(int,int)) || |
| call(void Point.setX(int)) || |
| call(void Point.setY(int)) || |
| call(void Line.setP1(Point)) || |
| call(void Line.setP2(Point)); |
| </pre><p> |
| and whenever this definition is visible, the programmer can simply |
| use <tt>move()</tt> to capture this complicated |
| pointcut. |
| </p><p> |
| The previous pointcuts are all based on explicit enumeration of a |
| set of method signatures. We sometimes call this |
| <span class="emphasis"><i>name-based</i></span> crosscutting. AspectJ also |
| provides mechanisms that enable specifying a pointcut in terms of |
| properties of methods other than their exact name. We call this |
| <span class="emphasis"><i>property-based</i></span> crosscutting. The simplest of |
| these involve using wildcards in certain fields of the method |
| signature. For example, the pointcut |
| </p><pre class="programlisting"> |
| call(void Figure.make*(..)) |
| </pre><p> |
| picks out each join point that's a call to a void method defined |
| on <tt>Figure</tt> whose the name begins with |
| "<tt>make</tt>" regardless of the method's parameters. |
| In our system, this picks out calls to the factory methods |
| <tt>makePoint</tt> and <tt>makeLine</tt>. |
| The pointcut |
| </p><pre class="programlisting"> |
| call(public * Figure.* (..)) |
| </pre><p> |
| picks out each call to <tt>Figure</tt>'s public |
| methods. |
| </p><p> |
| But wildcards aren't the only properties AspectJ supports. |
| Another pointcut, <tt>cflow</tt>, identifies join |
| points based on whether they occur in the dynamic context of |
| other join points. So |
| </p><pre class="programlisting"> |
| cflow(move()) |
| </pre><p> |
| picks out each join point that occurs in the dynamic context of |
| the join points picked out by <tt>move()</tt>, our named |
| pointcut defined above. So this picks out each join points that |
| occurrs between when a move method is called and when it returns |
| (either normally or by throwing an exception). |
| </p></div><div class="sect2"><a name="advice"></a><div class="titlepage"><div><h3 class="title"><a name="advice"></a>Advice</h3></div></div><p> |
| So pointcuts pick out join points. But they don't |
| <span class="emphasis"><i>do</i></span> anything apart from picking out join |
| points. To actually implement crosscutting behavior, we use |
| advice. Advice brings together a pointcut (to pick out join |
| points) and a body of code (to run at each of those join points). |
| </p><p> |
| AspectJ has several different kinds of advice. <span class="emphasis"><i>Before |
| advice</i></span> runs as a join point is reached, before the |
| program proceeds with the join point. For example, before advice |
| on a method call join point runs before the actual method starts |
| running, just after the arguments to the method call are evaluated. |
| </p><pre class="programlisting"> |
| before(): move() { |
| System.out.println("about to move"); |
| } |
| </pre><p> |
| <span class="emphasis"><i>After advice</i></span> on a particular join point runs |
| after the program proceeds with that join point. For example, |
| after advice on a method call join point runs after the method body |
| has run, just before before control is returned to the caller. |
| Because Java programs can leave a join point 'normally' or by |
| throwing an exception, there are three kinds of after advice: |
| <tt>after returning</tt>, <tt>after |
| throwing</tt>, and plain <tt>after</tt> (which runs |
| after returning <span class="emphasis"><i>or</i></span> throwing, like Java's |
| <tt>finally</tt>). |
| </p><pre class="programlisting"> |
| after() returning: move() { |
| System.out.println("just successfully moved"); |
| } |
| </pre><p> |
| <span class="emphasis"><i>Around advice</i></span> on a join point runs as the join |
| point is reached, and has explicit control over whether the program |
| proceeds with the join point. Around advice is not discussed in |
| this section. |
| </p><div class="sect3"><a name="d0e346"></a><div class="titlepage"><div><h4 class="title"><a name="d0e346"></a>Exposing Context in Pointcuts</h4></div></div><p> |
| Pointcuts not only pick out join points, they can also expose |
| part of the execution context at their join points. Values |
| exposed by a pointcut can be used in the body of advice |
| declarations. |
| </p><p> |
| An advice declaration has a parameter list (like a method) that |
| gives names to all the pieces of context that it uses. For |
| example, the after advice |
| </p><pre class="programlisting"> |
| after(FigureElement fe, int x, int y) returning: |
| ...SomePointcut... { |
| ...SomeBody... |
| } |
| </pre><p> |
| uses three pieces of exposed context, a |
| <tt>FigureElement</tt> named fe, and two |
| <tt>int</tt>s named x and y. |
| </p><p> |
| The body of the advice uses the names just like method |
| parameters, so |
| </p><pre class="programlisting"> |
| after(FigureElement fe, int x, int y) returning: |
| ...SomePointcut... { |
| System.out.println(fe + " moved to (" + x + ", " + y + ")"); |
| } |
| </pre><p> |
| The advice's pointcut publishes the values for the advice's |
| arguments. The three primitive pointcuts |
| <tt>this</tt>, <tt>target</tt> and |
| <tt>args</tt> are used to publish these values. So now |
| we can write the complete piece of advice: |
| </p><pre class="programlisting"> |
| after(FigureElement fe, int x, int y) returning: |
| call(void FigureElement.setXY(int, int)) |
| && target(fe) |
| && args(x, y) { |
| System.out.println(fe + " moved to (" + x + ", " + y + ")"); |
| } |
| </pre><p> |
| The pointcut exposes three values from calls to |
| <tt>setXY</tt>: the target |
| <tt>FigureElement</tt> -- which it publishes as |
| <tt>fe</tt>, so it becomes the first argument to the |
| after advice -- and the two int arguments -- which it publishes |
| as <tt>x</tt> and <tt>y</tt>, so they become |
| the second and third argument to the after advice. |
| </p><p> |
| So the advice prints the figure element |
| that was moved and its new <tt>x</tt> and |
| <tt>y</tt> coordinates after each |
| <tt>setXY</tt> method call. |
| </p><p> |
| A named pointcut may have parameters like a piece of advice. |
| When the named pointcut is used (by advice, or in another named |
| pointcut), it publishes its context by name just like the |
| <tt>this</tt>, <tt>target</tt> and |
| <tt>args</tt> pointcut. So another way to write the |
| above advice is |
| </p><pre class="programlisting"> |
| pointcut setXY(FigureElement fe, int x, int y): |
| call(void FigureElement.setXY(int, int)) |
| && target(fe) |
| && args(x, y); |
| |
| after(FigureElement fe, int x, int y) returning: setXY(fe, x, y) { |
| System.out.println(fe + " moved to (" + x + ", " + y + ")."); |
| } |
| </pre></div></div><div class="sect2"><a name="inter-type-declarations"></a><div class="titlepage"><div><h3 class="title"><a name="inter-type-declarations"></a>Inter-type declarations</h3></div></div><p> |
| Inter-type declarations in AspectJ are declarations that cut across |
| classes and their hierarchies. They may declare members that cut |
| across multiple classes, or change the inheritance relationship |
| between classes. Unlike advice, which operates primarily |
| dynamically, introduction operates statically, at compile-time. |
| </p><p> |
| Consider the problem of expressing a capability shared by some |
| existing classes that are already part of a class hierarchy, |
| i.e. they already extend a class. In Java, one creates an |
| interface that captures this new capability, and then adds to |
| <span class="emphasis"><i>each affected class</i></span> a method that implements |
| this interface. |
| </p><p> |
| AspectJ can express the concern in one place, by using inter-type |
| declarations. The aspect declares the methods and fields that are |
| necessary to implement the new capability, and associates the |
| methods and fields to the existing classes. |
| </p><p> |
| Suppose we want to have <tt>Screen</tt> objects |
| observe changes to <tt>Point</tt> objects, where |
| <tt>Point</tt> is an existing class. We can implement |
| this by writing an aspect declaring that the class Point |
| <tt>Point</tt> has an instance field, |
| <tt>observers</tt>, that keeps track of the |
| <tt>Screen</tt> objects that are observing |
| <tt>Point</tt>s. |
| </p><pre class="programlisting"> |
| aspect PointObserving { |
| private Vector Point.observers = new Vector(); |
| ... |
| } |
| </pre><p> |
| The <tt>observers</tt> field is private, so only |
| <tt>PointObserving</tt> can see it. So observers are |
| added or removed with the static methods |
| <tt>addObserver</tt> and |
| <tt>removeObserver</tt> on the aspect. |
| </p><pre class="programlisting"> |
| aspect PointObserving { |
| private Vector Point.observers = new Vector(); |
| |
| public static void addObserver(Point p, Screen s) { |
| p.observers.add(s); |
| } |
| public static void removeObserver(Point p, Screen s) { |
| p.observers.remove(s); |
| } |
| ... |
| } |
| </pre><p> |
| Along with this, we can define a pointcut |
| <tt>changes</tt> that defines what we want to observe, |
| and the after advice defines what we want to do when we observe a |
| change. |
| </p><pre class="programlisting"> |
| aspect PointObserving { |
| private Vector Point.observers = new Vector(); |
| |
| public static void addObserver(Point p, Screen s) { |
| p.observers.add(s); |
| } |
| public static void removeObserver(Point p, Screen s) { |
| p.observers.remove(s); |
| } |
| |
| pointcut changes(Point p): target(p) && call(void Point.set*(int)); |
| |
| after(Point p): changes(p) { |
| Iterator iter = p.observers.iterator(); |
| while ( iter.hasNext() ) { |
| updateObserver(p, (Screen)iter.next()); |
| } |
| } |
| |
| static void updateObserver(Point p, Screen s) { |
| s.display(p); |
| } |
| } |
| </pre><p> |
| Note that neither <tt>Screen</tt>'s nor |
| <tt>Point</tt>'s code has to be modified, and that |
| all the changes needed to support this new capability are local to |
| this aspect. |
| </p></div><div class="sect2"><a name="aspects"></a><div class="titlepage"><div><h3 class="title"><a name="aspects"></a>Aspects</h3></div></div><p> |
| Aspects wrap up pointcuts, advice, and inter-type declarations in a |
| a modular unit of crosscutting implementation. It is defined very |
| much like a class, and can have methods, fields, and initializers |
| in addition to the crosscutting members. Because only aspects may |
| include these crosscutting members, the declaration of these |
| effects is localized. |
| </p><p> |
| Like classes, aspects may be instantiated, but AspectJ controls how |
| that instantiation happens -- so you can't use Java's |
| <tt>new</tt> form to build new aspect instances. By |
| default, each aspect is a singleton, so one aspect instance is |
| created. This means that advice may use non-static fields of the |
| aspect, if it needs to keep state around: |
| </p><pre class="programlisting"> |
| aspect Logging { |
| OutputStream logStream = System.err; |
| |
| before(): move() { |
| logStream.println("about to move"); |
| } |
| } |
| </pre><p> |
| Aspects may also have more complicated rules for instantiation, but |
| these will be described in a later chapter. |
| </p></div></div><div class="sect1"><a name="starting-development"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="starting-development"></a>Development Aspects</h2></div></div><p> |
| The next two sections present the use of aspects in increasingly |
| sophisticated ways. Development aspects are easily removed from |
| production builds. Production aspects are intended to be used in |
| both development and in production, but tend to affect only a few |
| classes. |
| </p><p> |
| This section presents examples of aspects that can be used during |
| development of Java applications. These aspects facilitate debugging, |
| testing and performance tuning work. The aspects define behavior that |
| ranges from simple tracing, to profiling, to testing of internal |
| consistency within the application. Using AspectJ makes it possible |
| to cleanly modularize this kind of functionality, thereby making it |
| possible to easily enable and disable the functionality when desired. |
| </p><div class="sect2"><a name="tracing"></a><div class="titlepage"><div><h3 class="title"><a name="tracing"></a>Tracing</h3></div></div><p> |
| This first example shows how to increase the visibility of the |
| internal workings of a program. It is a simple tracing aspect that |
| prints a message at specified method calls. In our figure editor |
| example, one such aspect might simply trace whenever points are |
| drawn. |
| </p><pre class="programlisting"> |
| aspect SimpleTracing { |
| pointcut tracedCall(): |
| call(void FigureElement.draw(GraphicsContext)); |
| |
| before(): tracedCall() { |
| System.out.println("Entering: " + thisJoinPoint); |
| } |
| } |
| </pre><p> |
| This code makes use of the <tt>thisJoinPoint</tt> special |
| variable. Within all advice bodies this variable is bound to an |
| object that describes the current join point. The effect of this |
| code is to print a line like the following every time a figure |
| element receives a <tt>draw</tt> method call: |
| </p><pre class="programlisting"> |
| Entering: call(void FigureElement.draw(GraphicsContext)) |
| </pre><p> |
| To understand the benefit of coding this with AspectJ consider |
| changing the set of method calls that are traced. With AspectJ, |
| this just requires editing the definition of the |
| <tt>tracedCalls</tt> pointcut and recompiling. The |
| individual methods that are traced do not need to be edited. |
| </p><p> |
| When debugging, programmers often invest considerable effort in |
| figuring out a good set of trace points to use when looking for a |
| particular kind of problem. When debugging is complete or appears |
| to be complete it is frustrating to have to lose that investment by |
| deleting trace statements from the code. The alternative of just |
| commenting them out makes the code look bad, and can cause trace |
| statements for one kind of debugging to get confused with trace |
| statements for another kind of debugging. |
| </p><p> |
| With AspectJ it is easy to both preserve the work of designing a |
| good set of trace points and disable the tracing when it isn t |
| being used. This is done by writing an aspect specifically for that |
| tracing mode, and removing that aspect from the compilation when it |
| is not needed. |
| </p><p> |
| This ability to concisely implement and reuse debugging |
| configurations that have proven useful in the past is a direct |
| result of AspectJ modularizing a crosscutting design element the |
| set of methods that are appropriate to trace when looking for a |
| given kind of information. |
| </p></div><div class="sect2"><a name="profiling-and-logging"></a><div class="titlepage"><div><h3 class="title"><a name="profiling-and-logging"></a>Profiling and Logging</h3></div></div><p> |
| Our second example shows you how to do some very specific |
| profiling. Although many sophisticated profiling tools are |
| available, and these can gather a variety of information and |
| display the results in useful ways, you may sometimes want to |
| profile or log some very specific behavior. In these cases, it is |
| often possible to write a simple aspect similar to the ones above |
| to do the job. |
| </p><p> |
| For example, the following aspect counts the number of calls to the |
| <tt>rotate</tt> method on a <tt>Line</tt> |
| and the number of calls to the <tt>set*</tt> methods of |
| a <tt>Point</tt> that happen within the control flow |
| of those calls to <tt>rotate</tt>: |
| </p><pre class="programlisting"> |
| aspect SetsInRotateCounting { |
| int rotateCount = 0; |
| int setCount = 0; |
| |
| before(): call(void Line.rotate(double)) { |
| rotateCount++; |
| } |
| |
| before(): call(void Point.set*(int)) |
| && cflow(call(void Line.rotate(double))) { |
| setCount++; |
| } |
| } |
| </pre><p> |
| In effect, this aspect allows the programmer to ask very specific |
| questions like |
| |
| <blockquote class="blockquote"> |
| How many times is the <tt>rotate</tt> |
| method defined on <tt>Line</tt> objects called? |
| </blockquote> |
| |
| and |
| |
| <blockquote class="blockquote"> |
| How many times are methods defined on |
| <tt>Point</tt> objects whose name begins with |
| "<tt>set</tt>" called in fulfilling those rotate |
| calls? |
| </blockquote> |
| |
| questions it may be difficult to express using standard |
| profiling or logging tools. |
| </p></div><div class="sect2"><a name="pre-and-post-conditions"></a><div class="titlepage"><div><h3 class="title"><a name="pre-and-post-conditions"></a>Pre- and Post-Conditions</h3></div></div><p> |
| Many programmers use the "Design by Contract" style popularized by |
| Bertand Meyer in <i>Object-Oriented Software Construction, |
| 2/e</i>. In this style of programming, explicit |
| pre-conditions test that callers of a method call it properly and |
| explicit post-conditions test that methods properly do the work |
| they are supposed to. |
| </p><p> |
| AspectJ makes it possible to implement pre- and post-condition |
| testing in modular form. For example, this code |
| </p><pre class="programlisting"> |
| aspect PointBoundsChecking { |
| |
| pointcut setX(int x): |
| (call(void FigureElement.setXY(int, int)) && args(x, *)) |
| || (call(void Point.setX(int)) && args(x)); |
| |
| pointcut setY(int y): |
| (call(void FigureElement.setXY(int, int)) && args(*, y)) |
| || (call(void Point.setY(int)) && args(y)); |
| |
| before(int x): setX(x) { |
| if ( x < MIN_X || x > MAX_X ) |
| throw new IllegalArgumentException("x is out of bounds."); |
| } |
| |
| before(int y): setY(y) { |
| if ( y < MIN_Y || y > MAX_Y ) |
| throw new IllegalArgumentException("y is out of bounds."); |
| } |
| } |
| </pre><p> |
| implements the bounds checking aspect of pre-condition testing for |
| operations that move points. Notice that the |
| <tt>setX</tt> pointcut refers to all the operations |
| that can set a Point's <tt>x</tt> coordinate; this |
| includes the <tt>setX</tt> method, as well as half of |
| the <tt>setXY</tt> method. In this sense the |
| <tt>setX</tt> pointcut can be seen as involving very |
| fine-grained crosscutting — it names the the |
| <tt>setX</tt> method and half of the |
| <tt>setXY</tt> method. |
| </p><p> |
| Even though pre- and post-condition testing aspects can often be |
| used only during testing, in some cases developers may wish to |
| include them in the production build as well. Again, because |
| AspectJ makes it possible to modularize these crosscutting concerns |
| cleanly, it gives developers good control over this decision. |
| </p></div><div class="sect2"><a name="contract-enforcement"></a><div class="titlepage"><div><h3 class="title"><a name="contract-enforcement"></a>Contract Enforcement</h3></div></div><p> |
| The property-based crosscutting mechanisms can be very useful in |
| defining more sophisticated contract enforcement. One very powerful |
| use of these mechanisms is to identify method calls that, in a |
| correct program, should not exist. For example, the following |
| aspect enforces the constraint that only the well-known factory |
| methods can add an element to the registry of figure |
| elements. Enforcing this constraint ensures that no figure element |
| is added to the registry more than once. |
| </p><pre class="programlisting"> |
| aspect RegistrationProtection { |
| |
| pointcut register(): call(void Registry.register(FigureElement)); |
| |
| pointcut canRegister(): withincode(static * FigureElement.make*(..)); |
| |
| before(): register() && !canRegister() { |
| throw new IllegalAccessException("Illegal call " + thisJoinPoint); |
| } |
| } |
| </pre><p> |
| This aspect uses the withincode primitive pointcut to denote all |
| join points that occur within the body of the factory methods on |
| <tt>FigureElement</tt> (the methods with names that |
| begin with "<tt>make</tt>"). This is a property-based |
| pointcut because it identifies join points based not on their |
| signature, but rather on the property that they occur specifically |
| within the code of another method. The before advice declaration |
| effectively says signal an error for any calls to register that are |
| not within the factory methods. |
| </p><p> |
| This advice throws a runtime exception at certain join points, but |
| AspectJ can do better. Using the <tt>declare error</tt> |
| form, we can have the <span class="emphasis"><i>compiler</i></span> signal the |
| error. |
| </p><pre class="programlisting"> |
| aspect RegistrationProtection { |
| |
| pointcut register(): call(void Registry.register(FigureElement)); |
| pointcut canRegister(): withincode(static * FigureElement.make*(..)); |
| |
| declare error: register() && !canRegister(): "Illegal call" |
| } |
| </pre><p> |
| When using this aspect, it is impossible for the compiler to |
| compile programs with these illegal calls. This early detection is |
| not always possible. In this case, since we depend only on static |
| information (the <tt>withincode</tt> pointcut picks out |
| join points totally based on their code, and the |
| <tt>call</tt> pointcut here picks out join points |
| statically). Other enforcement, such as the precondition |
| enforcement, above, does require dynamic information such as the |
| runtime value of parameters. |
| </p></div><div class="sect2"><a name="configuration-management"></a><div class="titlepage"><div><h3 class="title"><a name="configuration-management"></a>Configuration Management</h3></div></div><p> |
| Configuration management for aspects can be handled using a variety |
| of make-file like techniques. To work with optional aspects, the |
| programmer can simply define their make files to either include the |
| aspect in the call to the AspectJ compiler or not, as desired. |
| </p><p> |
| Developers who want to be certain that no aspects are included in |
| the production build can do so by configuring their make files so |
| that they use a traditional Java compiler for production builds. To |
| make it easy to write such make files, the AspectJ compiler has a |
| command-line interface that is consistent with ordinary Java |
| compilers. |
| </p></div></div><div class="sect1"><a name="starting-production"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="starting-production"></a>Production Aspects</h2></div></div><p> |
| This section presents examples of aspects that are inherently |
| intended to be included in the production builds of an application. |
| Production aspects tend to add functionality to an application |
| rather than merely adding more visibility of the internals of a |
| program. Again, we begin with name-based aspects and follow with |
| property-based aspects. Name-based production aspects tend to |
| affect only a small number of methods. For this reason, they are a |
| good next step for projects adopting AspectJ. But even though they |
| tend to be small and simple, they can often have a significant |
| effect in terms of making the program easier to understand and |
| maintain. |
| </p><div class="sect2"><a name="change-monitoring"></a><div class="titlepage"><div><h3 class="title"><a name="change-monitoring"></a>Change Monitoring</h3></div></div><p> |
| The first example production aspect shows how one might implement |
| some simple functionality where it is problematic to try and do it |
| explicitly. It supports the code that refreshes the display. The |
| role of the aspect is to maintain a dirty bit indicating whether or |
| not an object has moved since the last time the display was |
| refreshed. |
| </p><p> |
| Implementing this functionality as an aspect is straightforward. |
| The <tt>testAndClear</tt> method is called by the |
| display code to find out whether a figure element has moved |
| recently. This method returns the current state of the dirty flag |
| and resets it to false. The pointcut <tt>move</tt> |
| captures all the method calls that can move a figure element. The |
| after advice on <tt>move</tt> sets the dirty flag |
| whenever an object moves. |
| </p><pre class="programlisting"> |
| aspect MoveTracking { |
| private static boolean dirty = false; |
| |
| public static boolean testAndClear() { |
| boolean result = dirty; |
| dirty = false; |
| return result; |
| } |
| |
| pointcut move(): |
| call(void FigureElement.setXY(int, int)) || |
| call(void Line.setP1(Point)) || |
| call(void Line.setP2(Point)) || |
| call(void Point.setX(int)) || |
| call(void Point.setY(int)); |
| |
| after() returning: move() { |
| dirty = true; |
| } |
| } |
| </pre><p> |
| Even this simple example serves to illustrate some of the important |
| benefits of using AspectJ in production code. Consider implementing |
| this functionality with ordinary Java: there would likely be a |
| helper class that contained the <tt>dirty</tt> flag, the |
| <tt>testAndClear</tt> method, as well as a |
| <tt>setFlag</tt> method. Each of the methods that could |
| move a figure element would include a call to the |
| <tt>setFlag</tt> method. Those calls, or rather the |
| concept that those calls should happen at each move operation, are |
| the crosscutting concern in this case. |
| </p><p> |
| The AspectJ implementation has several advantages over the standard |
| implementation: |
| </p><p> |
| <span class="emphasis"><i>The structure of the crosscutting concern is captured |
| explicitly.</i></span> The moves pointcut clearly states all the |
| methods involved, so the programmer reading the code sees not just |
| individual calls to <tt>setFlag</tt>, but instead sees |
| the real structure of the code. The IDE support included with |
| AspectJ automatically reminds the programmer that this aspect |
| advises each of the methods involved. The IDE support also |
| provides commands to jump to the advice from the method and |
| vice-versa. |
| </p><p> |
| <span class="emphasis"><i>Evolution is easier.</i></span> If, for example, the |
| aspect needs to be revised to record not just that some figure |
| element moved, but rather to record exactly which figure elements |
| moved, the change would be entirely local to the aspect. The |
| pointcut would be updated to expose the object being moved, and the |
| advice would be updated to record that object. The paper |
| <i>An Overview of AspectJ</i> (available linked off |
| of the AspectJ web site -- <a href="http://eclipse.org/aspectj" target="_top">http://eclipse.org/aspectj</a>), presented at ECOOP |
| 2001, presents a detailed discussion of various ways this aspect |
| could be expected to evolve. |
| </p><p> |
| <span class="emphasis"><i>The functionality is easy to plug in and out.</i></span> |
| Just as with development aspects, production aspects may need to be |
| removed from the system, either because the functionality is no |
| longer needed at all, or because it is not needed in certain |
| configurations of a system. Because the functionality is |
| modularized in a single aspect this is easy to do. |
| </p><p> |
| <span class="emphasis"><i>The implementation is more stable.</i></span> If, for |
| example, the programmer adds a subclass of |
| <tt>Line</tt> that overrides the existing methods, |
| this advice in this aspect will still apply. In the ordinary Java |
| implementation the programmer would have to remember to add the |
| call to <tt>setFlag</tt> in the new overriding |
| method. This benefit is often even more compelling for |
| property-based aspects (see the section <a href="#starting-production-consistentBehavior">Providing Consistent Behavior</a>). |
| </p></div><div class="sect2"><a name="context-passing"></a><div class="titlepage"><div><h3 class="title"><a name="context-passing"></a>Context Passing</h3></div></div><p> |
| The crosscutting structure of context passing can be a significant |
| source of complexity in Java programs. Consider implementing |
| functionality that would allow a client of the figure editor (a |
| program client rather than a human) to set the color of any figure |
| elements that are created. Typically this requires passing a color, |
| or a color factory, from the client, down through the calls that |
| lead to the figure element factory. All programmers are familiar |
| with the inconvenience of adding a first argument to a number of |
| methods just to pass this kind of context information. |
| </p><p> |
| Using AspectJ, this kind of context passing can be implemented in a |
| modular way. The following code adds after advice that runs only |
| when the factory methods of <tt>Figure</tt> are |
| called in the control flow of a method on a |
| <tt>ColorControllingClient</tt>. |
| </p><pre class="programlisting"> |
| aspect ColorControl { |
| pointcut CCClientCflow(ColorControllingClient client): |
| cflow(call(* * (..)) && target(client)); |
| |
| pointcut make(): call(FigureElement Figure.make*(..)); |
| |
| after (ColorControllingClient c) returning (FigureElement fe): |
| make() && CCClientCflow(c) { |
| fe.setColor(c.colorFor(fe)); |
| } |
| } |
| </pre><p> |
| This aspect affects only a small number of methods, but note that |
| the non-AOP implementation of this functionality might require |
| editing many more methods, specifically, all the methods in the |
| control flow from the client to the factory. This is a benefit |
| common to many property-based aspects while the aspect is short and |
| affects only a modest number of benefits, the complexity the aspect |
| saves is potentially much larger. |
| </p></div><div class="sect2"><a name="starting-production-consistentBehavior"></a><div class="titlepage"><div><h3 class="title"><a name="starting-production-consistentBehavior"></a>Providing Consistent Behavior</h3></div></div><p> |
| This example shows how a property-based aspect can be used to |
| provide consistent handling of functionality across a large set of |
| operations. This aspect ensures that all public methods of the |
| <tt>com.bigboxco</tt> package log any Errors they throw |
| to their caller (in Java, an Error is like an Exception, but it |
| indicates that something really bad and usually unrecoverable has |
| happened). The <tt>publicMethodCall</tt> pointcut |
| captures the public method calls of the package, and the after |
| advice runs whenever one of those calls throws an Error. The advice |
| logs that Error and then the throw resumes. |
| </p><pre class="programlisting"> |
| aspect PublicErrorLogging { |
| Log log = new Log(); |
| |
| pointcut publicMethodCall(): |
| call(public * com.bigboxco.*.*(..)); |
| |
| after() throwing (Error e): publicMethodCall() { |
| log.write(e); |
| } |
| } |
| </pre><p> |
| In some cases this aspect can log an exception twice. This happens |
| if code inside the <tt>com.bigboxco</tt> package itself |
| calls a public method of the package. In that case this code will |
| log the error at both the outermost call into the |
| <tt>com.bigboxco</tt> package and the re-entrant |
| call. The <tt>cflow</tt> primitive pointcut can be used |
| in a nice way to exclude these re-entrant calls:</p><pre class="programlisting"> |
| after() throwing (Error e): |
| publicMethodCall() && !cflow(publicMethodCall()) { |
| log.write(e); |
| } |
| </pre><p> |
| The following aspect is taken from work on the AspectJ compiler. |
| The aspect advises about 35 methods in the |
| <tt>JavaParser</tt> class. The individual methods |
| handle each of the different kinds of elements that must be |
| parsed. They have names like <tt>parseMethodDec</tt>, |
| <tt>parseThrows</tt>, and |
| <tt>parseExpr</tt>. |
| </p><pre class="programlisting"> |
| aspect ContextFilling { |
| pointcut parse(JavaParser jp): |
| call(* JavaParser.parse*(..)) |
| && target(jp) |
| && !call(Stmt parseVarDec(boolean)); // var decs |
| // are tricky |
| |
| around(JavaParser jp) returns ASTObject: parse(jp) { |
| Token beginToken = jp.peekToken(); |
| ASTObject ret = proceed(jp); |
| if (ret != null) jp.addContext(ret, beginToken); |
| return ret; |
| } |
| } |
| </pre><p> |
| This example exhibits a property found in many aspects with large |
| property-based pointcuts. In addition to a general property based |
| pattern <tt>call(* JavaParser.parse*(..))</tt> it |
| includes an exception to the pattern <tt>!call(Stmt |
| parseVarDec(boolean))</tt>. The exclusion of |
| <tt>parseVarDec</tt> happens because the parsing of |
| variable declarations in Java is too complex to fit with the clean |
| pattern of the other <tt>parse*</tt> methods. Even with |
| the explicit exclusion this aspect is a clear expression of a clean |
| crosscutting modularity. Namely that all |
| <tt>parse*</tt> methods that return |
| <tt>ASTObjects</tt>, except for |
| <tt>parseVarDec</tt> share a common behavior for |
| establishing the parse context of their result. |
| </p><p> |
| The process of writing an aspect with a large property-based |
| pointcut, and of developing the appropriate exceptions can clarify |
| the structure of the system. This is especially true, as in this |
| case, when refactoring existing code to use aspects. When we first |
| looked at the code for this aspect, we were able to use the IDE |
| support provided in AJDE for JBuilder to see what methods the |
| aspect was advising compared to our manual coding. We quickly |
| discovered that there were a dozen places where the aspect advice |
| was in effect but we had not manually inserted the required |
| functionality. Two of these were bugs in our prior non-AOP |
| implementation of the parser. The other ten were needless |
| performance optimizations. So, here, refactoring the code to |
| express the crosscutting structure of the aspect explicitly made |
| the code more concise and eliminated latent bugs. |
| </p></div></div><div class="sect1"><a name="starting-conclusion"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="starting-conclusion"></a>Conclusion</h2></div></div><p> |
| AspectJ is a simple and practical aspect-oriented extension to |
| Java. With just a few new constructs, AspectJ provides support for |
| modular implementation of a range of crosscutting concerns. |
| </p><p> |
| Adoption of AspectJ into an existing Java development project can be |
| a straightforward and incremental task. One path is to begin by using |
| only development aspects, going on to using production aspects and |
| then reusable aspects after building up experience with |
| AspectJ. Adoption can follow other paths as well. For example, some |
| developers will benefit from using production aspects right |
| away. Others may be able to write clean reusable aspects almost right |
| away. |
| </p><p> |
| AspectJ enables both name-based and property based crosscutting. |
| Aspects that use name-based crosscutting tend to affect a small |
| number of other classes. But despite their small scale, they can |
| often eliminate significant complexity compared to an ordinary Java |
| implementation. Aspects that use property-based crosscutting can |
| have small or large scale. |
| </p><p> |
| Using AspectJ results in clean well-modularized implementations of |
| crosscutting concerns. When written as an AspectJ aspect the |
| structure of a crosscutting concern is explicit and easy to |
| understand. Aspects are also highly modular, making it possible to |
| develop plug-and-play implementations of crosscutting |
| functionality. |
| </p><p> |
| AspectJ provides more functionality than was covered by this short |
| introduction. The next chapter, <a href="#language">The AspectJ Language</a>, |
| covers in detail more of the features of the AspectJ language. The |
| following chapter, <a href="#examples">Examples</a>, then presents some |
| carefully chosen examples that show you how AspectJ might be used. We |
| recommend that you read the next two chapters carefully before |
| deciding to adopt AspectJ into a project. |
| </p></div></div><div class="chapter"><div class="titlepage"><div><h2 class="title"><a name="language"></a>Chapter 2. The AspectJ Language</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#language-intro">Introduction</a></dt><dt><a href="#language-anatomy">The Anatomy of an Aspect</a></dt><dd><dl><dt><a href="#an-example-aspect">An Example Aspect</a></dt><dt><a href="#pointcuts">Pointcuts</a></dt><dt><a href="#advice">Advice</a></dt></dl></dd><dt><a href="#language-joinPoints">Join Points and Pointcuts</a></dt><dd><dl><dt><a href="#some-example-pointcuts">Some Example Pointcuts</a></dt><dt><a href="#call-vs-execution">call vs. execution</a></dt><dt><a href="#pointcut-composition">Pointcut composition</a></dt><dt><a href="#pointcut-parameters">Pointcut Parameters</a></dt><dt><a href="#example">Example: <tt>HandleLiveness</tt></a></dt></dl></dd><dt><a href="#language-advice">Advice</a></dt><dt><a href="#language-interType">Inter-type declarations</a></dt><dd><dl><dt><a href="#inter-type-scope">Inter-type Scope</a></dt><dt><a href="#example-pointassertions">Example: <tt>PointAssertions</tt></a></dt></dl></dd><dt><a href="#language-thisJoinPoint">thisJoinPoint</a></dt></dl></div><div class="sect1"><a name="language-intro"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-intro"></a>Introduction</h2></div></div><p> |
| The previous chapter, <a href="#starting">Getting Started with AspectJ</a>, was a brief |
| overview of the AspectJ language. You should read this chapter to |
| understand AspectJ's syntax and semantics. It covers the same |
| material as the previous chapter, but more completely and in much |
| more detail. |
| </p><p> |
| We will start out by looking at an example aspect that we'll build |
| out of a pointcut, an introduction, and two pieces of advice. This |
| example aspect will gives us something concrete to talk about. |
| </p></div><div class="sect1"><a name="language-anatomy"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-anatomy"></a>The Anatomy of an Aspect</h2></div></div><p> |
| This lesson explains the parts of AspectJ's aspects. By reading this |
| lesson you will have an overview of what's in an aspect and you will |
| be exposed to the new terminology introduced by AspectJ. |
| </p><div class="sect2"><a name="an-example-aspect"></a><div class="titlepage"><div><h3 class="title"><a name="an-example-aspect"></a>An Example Aspect</h3></div></div><p> |
| Here's an example of an aspect definition in AspectJ: |
| </p><pre class="programlisting"> |
| 1 aspect FaultHandler { |
| 2 |
| 3 private boolean Server.disabled = false; |
| 4 |
| 5 private void reportFault() { |
| 6 System.out.println("Failure! Please fix it."); |
| 7 } |
| 8 |
| 9 public static void fixServer(Server s) { |
| 10 s.disabled = false; |
| 11 } |
| 12 |
| 13 pointcut services(Server s): target(s) && call(public * *(..)); |
| 14 |
| 15 before(Server s): services(s) { |
| 16 if (s.disabled) throw new DisabledException(); |
| 17 } |
| 18 |
| 19 after(Server s) throwing (FaultException e): services(s) { |
| 20 s.disabled = true; |
| 21 reportFault(); |
| 22 } |
| 23 } |
| </pre><p> |
| The <tt>FaultHandler</tt> consists of one inter-type |
| field on <tt>Server</tt> (line 03), two methods (lines |
| 05-07 and 09-11), one pointcut definition (line 13), and two pieces |
| of advice (lines 15-17 and 19-22). |
| </p><p> |
| This covers the basics of what aspects can contain. In general, |
| aspects consist of an association of other program entities, |
| ordinary variables and methods, pointcut definitions, inter-type declarations, |
| and advice, where advice may be before, after or around advice. The |
| remainder of this lesson focuses on those crosscut-related |
| constructs. |
| </p></div><div class="sect2"><a name="pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="pointcuts"></a>Pointcuts</h3></div></div><p> |
| AspectJ's pointcut definitions give names to pointcuts. Pointcuts |
| themselves pick out join points, i.e. interesting points in the |
| execution of a program. These join points can be method or |
| constructor invocations and executions, the handling of exceptions, |
| field assignments and accesses, etc. Take, for example, the |
| pointcut definition in line 13: |
| </p><pre class="programlisting"> |
| pointcut services(Server s): target(s) && call(public * *(..)) |
| </pre><p> |
| This pointcut, named <tt>services</tt>, picks out those |
| points in the execution of the program when |
| <tt>Server</tt> objects have their public methods called. |
| It also allows anyone using the <tt>services</tt> |
| pointcut to access the <tt>Server</tt> object whose |
| method is being called. |
| </p><p> |
| The idea behind this pointcut in the |
| <tt>FaultHandler</tt> aspect is that |
| fault-handling-related behavior must be triggered on the calls to |
| public methods. For example, the server may be unable to proceed |
| with the request because of some fault. The calls of those methods |
| are, therefore, interesting events for this aspect, in the sense |
| that certain fault-related things will happen when these events |
| occur. |
| </p><p> |
| Part of the context in which the events occur is exposed by the |
| formal parameters of the pointcut. In this case, that consists of |
| objects of type <tt>Server</tt>. That formal parameter |
| is then being used on the right hand side of the declaration in |
| order to identify which events the pointcut refers to. In this |
| case, a pointcut picking out join points where a Server is the |
| target of some operation (target(s)) is being composed |
| (<tt>&&</tt>, meaning and) with a pointcut |
| picking out call join points (call(...)). The calls are identified |
| by signatures that can include wild cards. In this case, there are |
| wild cards in the return type position (first *), in the name |
| position (second *) and in the argument list position (..); the |
| only concrete information is given by the qualifier |
| <tt>public</tt>. |
| </p><p> |
| Pointcuts pick out arbitrarily large numbers of join points of a |
| program. But they pick out only a small number of |
| <span class="emphasis"><i>kinds</i></span> of join points. Those kinds of join |
| points correspond to some of the most important concepts in |
| Java. Here is an incomplete list: method call, method execution, |
| exception handling, instantiation, constructor execution, and |
| field access. Each kind of join point can be picked out by its |
| own specialized pointcut that you will learn about in other parts |
| of this guide. |
| </p></div><div class="sect2"><a name="advice"></a><div class="titlepage"><div><h3 class="title"><a name="advice"></a>Advice</h3></div></div><p> |
| A piece of advice brings together a pointcut and a body of code to |
| define aspect implementation that runs at join points picked out by |
| the pointcut. For example, the advice in lines 15-17 specifies that |
| the following piece of code |
| </p><pre class="programlisting"> |
| { |
| if (s.disabled) throw new DisabledException(); |
| } |
| </pre><p> |
| is executed when instances of the <tt>Server</tt> class |
| have their public methods called, as specified by the pointcut |
| <tt>services</tt>. More specifically, it runs when those |
| calls are made, just before the corresponding methods are executed. |
| </p><p> |
| The advice in lines 19-22 defines another piece of implementation |
| that is executed on the same pointcut: |
| </p><pre class="programlisting"> |
| { |
| s.disabled = true; |
| reportFault(); |
| } |
| </pre><p> |
| But this second method executes after those operations throw |
| exception of type <tt>FaultException</tt>. |
| </p><p> |
| There are two other variations of after advice: upon successful |
| return and upon return, either successful or with an exception. |
| There is also a third kind of advice called around. You will see |
| those in other parts of this guide. |
| </p></div></div><div class="sect1"><a name="language-joinPoints"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-joinPoints"></a>Join Points and Pointcuts</h2></div></div><p> |
| Consider the following Java class: |
| </p><pre class="programlisting"> |
| class Point { |
| private int x, y; |
| |
| Point(int x, int y) { this.x = x; this.y = y; } |
| |
| void setX(int x) { this.x = x; } |
| void setY(int y) { this.y = y; } |
| |
| int getX() { return x; } |
| int getY() { return y; } |
| } |
| </pre><p> |
| In order to get an intuitive understanding of AspectJ's join points |
| and pointcuts, let's go back to some of the basic principles of |
| Java. Consider the following a method declaration in class Point: |
| </p><pre class="programlisting"> |
| void setX(int x) { this.x = x; } |
| </pre><p> |
| This piece of program says that that when method named |
| <tt>setX</tt> with an <tt>int</tt> argument |
| called on an object of type <tt>Point</tt>, then the method |
| body <tt>{ this.x = x; }</tt> is executed. Similarly, the |
| constructor of the class states that when an object of type |
| <tt>Point</tt> is instantiated through a constructor with |
| two <tt>int</tt> arguments, then the constructor body |
| <tt>{ this.x = x; this.y = y; }</tt> is executed. |
| </p><p> |
| One pattern that emerges from these descriptions is |
| |
| <blockquote class="blockquote"> |
| When something happens, then something gets executed. |
| </blockquote> |
| |
| In object-oriented programs, there are several kinds of "things that |
| happen" that are determined by the language. We call these the join |
| points of Java. Join points consist of things like method calls, |
| method executions, object instantiations, constructor executions, |
| field references and handler executions. (See the <a href="#quick">AspectJ Quick Reference</a> for a complete listing.) |
| </p><p> |
| Pointcuts pick out these join points. For example, the pointcut |
| </p><pre class="programlisting"> |
| pointcut setter(): target(Point) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| picks out each call to <tt>setX(int)</tt> or |
| <tt>setY(int)</tt> when called on an instance of |
| <tt>Point</tt>. Here's another example: |
| </p><pre class="programlisting"> |
| pointcut ioHandler(): within(MyClass) && handler(IOException); |
| </pre><p> |
| This pointcut picks out each the join point when exceptions of type |
| <tt>IOException</tt> are handled inside the code defined by |
| class <tt>MyClass</tt>. |
| </p><p> |
| Pointcut definitions consist of a left-hand side and a right-hand side, |
| separated by a colon. The left-hand side consists of the pointcut name |
| and the pointcut parameters (i.e. the data available when the events |
| happen). The right-hand side consists of the pointcut itself. |
| </p><div class="sect2"><a name="some-example-pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="some-example-pointcuts"></a>Some Example Pointcuts</h3></div></div><p> |
| Here are examples of pointcuts picking out |
| </p><div class="variablelist"><dl><dt><a name="d0e1024"></a><span class="term">when a particular method body executes</span></dt><dd><p><a name="d0e1027"></a> |
| <tt>execution(void Point.setX(int))</tt> |
| </p></dd><dt><a name="d0e1033"></a><span class="term">when a method is called</span></dt><dd><p><a name="d0e1036"></a> |
| <tt>call(void Point.setX(int))</tt> |
| </p></dd><dt><a name="d0e1042"></a><span class="term">when an exception handler executes</span></dt><dd><p><a name="d0e1045"></a> |
| <tt>handler(ArrayOutOfBoundsException)</tt> |
| </p></dd><dt><a name="d0e1051"></a><span class="term"> |
| when the object currently executing |
| (i.e. <tt>this</tt>) is of type |
| <tt>SomeType</tt> |
| </span></dt><dd><p><a name="d0e1060"></a> |
| <tt>this(SomeType)</tt> |
| </p></dd><dt><a name="d0e1066"></a><span class="term"> |
| when the target object is of type <tt>SomeType</tt> |
| </span></dt><dd><p><a name="d0e1072"></a> |
| <tt>target(SomeType)</tt> |
| </p></dd><dt><a name="d0e1078"></a><span class="term"> |
| when the executing code belongs to |
| class <tt>MyClass</tt> |
| </span></dt><dd><p><a name="d0e1084"></a> |
| <tt>within(MyClass)</tt> |
| </p></dd><dt><a name="d0e1090"></a><span class="term"> |
| when the join point is in the control flow of a call to a |
| <tt>Test</tt>'s no-argument <tt>main</tt> |
| method |
| </span></dt><dd><p><a name="d0e1099"></a> |
| <tt>cflow(call(void Test.main()))</tt> |
| </p></dd></dl></div><p> |
| Pointcuts compose through the operations <tt>or</tt> |
| ("<tt>||</tt>"), <tt>and</tt> |
| ("<tt>&&</tt>") and <tt>not</tt> |
| ("<tt>!</tt>"). |
| </p><div class="itemizedlist"><ul><li><p><a name="d0e1126"></a> |
| It is possible to use wildcards. So |
| |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1130"></a> |
| <tt>execution(* *(..))</tt> |
| </p></li><li><p><a name="d0e1136"></a> |
| <tt>call(* set(..))</tt> |
| </p></li></ol></div> |
| |
| means (1) the execution of any method regardless of return or |
| parameter types, and (2) the call to any method named |
| <tt>set</tt> regardless of return or parameter types |
| -- in case of overloading there may be more than one such |
| <tt>set</tt> method; this pointcut picks out calls to |
| all of them. |
| </p></li><li><p><a name="d0e1149"></a> |
| You can select elements based on types. For example, |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1153"></a> |
| <tt>execution(int *())</tt> |
| </p></li><li><p><a name="d0e1159"></a> |
| <tt>call(* setY(long))</tt> |
| </p></li><li><p><a name="d0e1165"></a> |
| <tt>call(* Point.setY(int))</tt> |
| </p></li><li><p><a name="d0e1171"></a> |
| <tt>call(*.new(int, int))</tt> |
| </p></li></ol></div> |
| |
| means (1) the execution of any method with no parameters that |
| returns an <tt>int</tt>, (2) the call to any |
| <tt>setY</tt> method that takes a |
| <tt>long</tt> as an argument, regardless of return |
| type or declaring type, (3) the call to any of |
| <tt>Point</tt>'s <tt>setY</tt> methods that |
| take an <tt>int</tt> as an argument, regardless of |
| return type, and (4) the call to any classes' constructor, so |
| long as it takes exactly two <tt>int</tt>s as |
| arguments. |
| </p></li><li><p><a name="d0e1199"></a> |
| You can compose pointcuts. For example, |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1203"></a> |
| <tt>target(Point) && call(int *())</tt> |
| </p></li><li><p><a name="d0e1209"></a> |
| <tt>call(* *(..)) && (within(Line) || within(Point))</tt> |
| </p></li><li><p><a name="d0e1215"></a> |
| <tt>within(*) && execution(*.new(int))</tt> |
| </p></li><li><p><a name="d0e1221"></a> |
| <tt> |
| !this(Point) && call(int *(..)) |
| </tt> |
| </p></li></ol></div> |
| |
| means (1) any call to an <tt>int</tt> method with no |
| arguments on an instance of <tt>Point</tt>, |
| regardless of its name, (2) any call to any method where the |
| call is made from the code in <tt>Point</tt>'s or |
| <tt>Line</tt>'s type declaration, (3) the execution of |
| any constructor taking exactly one <tt>int</tt> |
| argument, regardless of where the call is made from, and |
| (4) any method call to an <tt>int</tt> method when |
| the executing object is any type except <tt>Point</tt>. |
| </p></li><li><p><a name="d0e1249"></a> |
| You can select methods and constructors based on their |
| modifiers and on negations of modifiers. For example, you can |
| say: |
| <div class="orderedlist"><ol type="1"><li><p><a name="d0e1253"></a> |
| <tt>call(public * *(..))</tt> |
| </p></li><li><p><a name="d0e1259"></a> |
| <tt>execution(!static * *(..))</tt> |
| </p></li><li><p><a name="d0e1265"></a> |
| <tt> execution(public !static * *(..))</tt> |
| </p></li></ol></div> |
| which means (1) any call to a public method, (2) any |
| execution of a non-static method, and (3) any execution of a |
| public, non-static method. |
| </p></li><li><p><a name="d0e1272"></a> |
| Pointcuts can also deal with interfaces. For example, given the |
| interface </p><pre class="programlisting"> |
| interface MyInterface { ... } |
| </pre><p> |
| the pointcut <tt>call(* MyInterface.*(..))</tt> picks |
| out any call to a method in <tt>MyInterface</tt>'s |
| signature -- that is, any method defined by |
| <tt>MyInterface</tt> or inherited by one of its a |
| supertypes. |
| </p></li></ul></div></div><div class="sect2"><a name="call-vs-execution"></a><div class="titlepage"><div><h3 class="title"><a name="call-vs-execution"></a>call vs. execution</h3></div></div><p> |
| When methods and constructors run, there are two interesting times |
| associated with them. That is when they are called, and when they |
| actually execute. |
| </p><p> |
| AspectJ exposes these times as call and execution join points, |
| respectively, and allows them to be picked out specifically by |
| <tt>call</tt> and <tt>execution</tt> pointcuts. |
| </p><p> |
| So what's the difference between these join points? Well, there are a |
| number of differences: |
| </p><p> |
| Firstly, the lexical pointcut declarations |
| <tt>within</tt> and <tt>withincode</tt> match |
| differently. At a call join point, the enclosing code is that of |
| the call site. This means that <tt>call(void m()) |
| && withincode(void m())</tt> will only capture |
| directly recursive calls, for example. At an execution join point, |
| however, the program is already executing the method, so the |
| enclosing code is the method itself: <tt>execution(void m()) |
| && withincode(void m())</tt> is the same as |
| <tt>execution(void m())</tt>. |
| </p><p> |
| Secondly, the call join point does not capture super calls to |
| non-static methods. This is because such super calls are different in |
| Java, since they don't behave via dynamic dispatch like other calls to |
| non-static methods. |
| </p><p> |
| The rule of thumb is that if you want to pick a join point that |
| runs when an actual piece of code runs (as is often the case for |
| tracing), use <tt>execution</tt>, but if you want to pick |
| one that runs when a particular <span class="emphasis"><i>signature</i></span> is |
| called (as is often the case for production aspects), use |
| <tt>call</tt>. |
| </p></div><div class="sect2"><a name="pointcut-composition"></a><div class="titlepage"><div><h3 class="title"><a name="pointcut-composition"></a>Pointcut composition</h3></div></div><p> |
| Pointcuts are put together with the operators and (spelled |
| <tt>&&</tt>), or (spelled <tt>||</tt>), |
| and not (spelled <tt>!</tt>). This allows the creation |
| of very powerful pointcuts from the simple building blocks of |
| primitive pointcuts. This composition can be somewhat confusing |
| when used with primitive pointcuts like <tt>cflow</tt> |
| and <tt>cflowbelow</tt>. Here's an example: |
| </p><p> |
| <tt>cflow(<i><tt>P</tt></i>)</tt> picks out |
| each join point in the control flow of the join points picked out |
| by <i><tt>P</tt></i>. So, pictorially: |
| </p><pre class="programlisting"> |
| P --------------------- |
| \ |
| \ cflow of P |
| \ |
| </pre><p> |
| What does <tt>cflow(<i><tt>P</tt></i>) && |
| cflow(<i><tt>Q</tt></i>)</tt> pick out? Well, it |
| picks out each join point that is in both the control flow of |
| <i><tt>P</tt></i> and in the control flow of |
| <i><tt>Q</tt></i>. So... |
| </p><pre class="programlisting"> |
| P --------------------- |
| \ |
| \ cflow of P |
| \ |
| \ |
| \ |
| Q -------------\------- |
| \ \ |
| \ cflow of Q \ cflow(P) && cflow(Q) |
| \ \ |
| </pre><p> |
| Note that <i><tt>P</tt></i> and |
| <i><tt>Q</tt></i> might not have any join points in |
| common... but their control flows might have join points in common. |
| </p><p> |
| But what does <tt>cflow(<i><tt>P</tt></i> |
| && <i><tt>Q</tt></i>)</tt> mean? Well, it |
| means the control flow of those join points that are both picked |
| out by <i><tt>P</tt></i> and picked out by |
| <i><tt>Q</tt></i>. |
| </p><pre class="programlisting"> |
| P && Q ------------------- |
| \ |
| \ cflow of (P && Q) |
| \ |
| </pre><p> |
| and if there are <span class="emphasis"><i>no</i></span> join points that are both |
| picked by <i><tt>P</tt></i> and picked out by |
| <i><tt>Q</tt></i>, then there's no chance that there are |
| any join points in the control flow of |
| <tt>(<i><tt>P</tt></i> && |
| <i><tt>Q</tt></i>)</tt>. |
| </p><p> |
| Here's some code that expresses this. |
| </p><pre class="programlisting"> |
| public class Test { |
| public static void main(String[] args) { |
| foo(); |
| } |
| static void foo() { |
| goo(); |
| } |
| static void goo() { |
| System.out.println("hi"); |
| } |
| } |
| |
| aspect A { |
| pointcut fooPC(): execution(void Test.foo()); |
| pointcut gooPC(): execution(void Test.goo()); |
| pointcut printPC(): call(void java.io.PrintStream.println(String)); |
| |
| before(): cflow(fooPC()) && cflow(gooPC()) && printPC() && !within(A) { |
| System.out.println("should occur"); |
| } |
| |
| before(): cflow(fooPC() && gooPC()) && printPC() && !within(A) { |
| System.out.println("should not occur"); |
| } |
| } |
| </pre><p> |
| The <tt>!within(<i><tt>A</tt></i>)</tt> |
| pointcut above is required to avoid the <tt>printPC</tt> |
| pointcut applying to the <tt>System.out.println</tt> |
| call in the advice body. If this was not present a recursive call |
| would result as the pointcut would apply to it's own advice. |
| (See <a href="#pitfalls-infiniteLoops" title="Infinite loops">the section called “Infinite loops”</a> for more details.) |
| </p></div><div class="sect2"><a name="pointcut-parameters"></a><div class="titlepage"><div><h3 class="title"><a name="pointcut-parameters"></a>Pointcut Parameters</h3></div></div><p> |
| Consider again the first pointcut definition in this chapter: |
| </p><pre class="programlisting"> |
| pointcut setter(): target(Point) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| As we've seen, this pointcut picks out each call to |
| <tt>setX(int)</tt> or <tt>setY(int)</tt> |
| methods where the target is an instance of |
| <tt>Point</tt>. The pointcut is given the name |
| <tt>setters</tt> and no parameters on the left-hand |
| side. An empty parameter list means that none of the context from |
| the join points is published from this pointcut. But consider |
| another version of version of this pointcut definition: |
| </p><pre class="programlisting"> |
| pointcut setter(Point p): target(p) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| This version picks out exactly the same join points. But in this |
| version, the pointcut has one parameter of type |
| <tt>Point</tt>. This means that any advice that uses this |
| pointcut has access to a <tt>Point</tt> from each join |
| point picked out by the pointcut. Inside the pointcut definition |
| this <tt>Point</tt> is named <tt>p</tt> is |
| available, and according to the right-hand side of the definition, |
| that <tt>Point p</tt> comes from the |
| <tt>target</tt> of each matched join point. |
| </p><p> |
| Here's another example that illustrates the flexible mechanism for |
| defining pointcut parameters: |
| </p><pre class="programlisting"> |
| pointcut testEquality(Point p): target(Point) && |
| args(p) && |
| call(boolean equals(Object)); |
| </pre><p> |
| This pointcut also has a parameter of type |
| <tt>Point</tt>. Similar to the |
| <tt>setters</tt> pointcut, this means that anyone using |
| this pointcut has access to a <tt>Point</tt> from each |
| join point. But in this case, looking at the right-hand side we |
| find that the object named in the parameters is not the target |
| <tt>Point</tt> object that receives the call; it's the |
| argument (also of type <tt>Point</tt>) passed to the |
| <tt>equals</tt> method when some other |
| <tt>Point</tt> is the target. If we wanted access to both |
| <tt>Point</tt>s, then the pointcut definition that would |
| expose target <tt>Point p1</tt> and argument |
| <tt>Point p2</tt> would be |
| </p><pre class="programlisting"> |
| pointcut testEquality(Point p1, Point p2): target(p1) && |
| args(p2) && |
| call(boolean equals(Object)); |
| </pre><p> |
| Let's look at another variation of the <tt>setters</tt> pointcut: |
| </p><pre class="programlisting"> |
| pointcut setter(Point p, int newval): target(p) && |
| args(newval) && |
| (call(void setX(int)) || |
| call(void setY(int))); |
| </pre><p> |
| In this case, a <tt>Point</tt> object and an |
| <tt>int</tt> value are exposed by the named |
| pointcut. Looking at the the right-hand side of the definition, we |
| find that the <tt>Point</tt> object is the target object, |
| and the <tt>int</tt> value is the called method's |
| argument. |
| </p><p> |
| The use of pointcut parameters is relatively flexible. The most |
| important rule is that all the pointcut parameters must be bound at |
| every join point picked out by the pointcut. So, for example, the |
| following pointcut definition will result in a compilation error: |
| |
| <pre class="programlisting"> |
| pointcut badPointcut(Point p1, Point p2): |
| (target(p1) && call(void setX(int))) || |
| (target(p2) && call(void setY(int))); |
| </pre> |
| |
| because <tt>p1</tt> is only bound when calling |
| <tt>setX</tt>, and <tt>p2</tt> is only bound |
| when calling <tt>setY</tt>, but the pointcut picks out |
| all of these join points and tries to bind both |
| <tt>p1</tt> and <tt>p2</tt>. |
| </p></div><div class="sect2"><a name="example"></a><div class="titlepage"><div><h3 class="title"><a name="example"></a>Example: <tt>HandleLiveness</tt></h3></div></div><p> |
| The example below consists of two object classes (plus an exception |
| class) and one aspect. Handle objects delegate their public, |
| non-static operations to their <tt>Partner</tt> |
| objects. The aspect <tt>HandleLiveness</tt> ensures that, |
| before the delegations, the partner exists and is alive, or else it |
| throws an exception. |
| </p><pre class="programlisting"> |
| class Handle { |
| Partner partner = new Partner(); |
| |
| public void foo() { partner.foo(); } |
| public void bar(int x) { partner.bar(x); } |
| |
| public static void main(String[] args) { |
| Handle h1 = new Handle(); |
| h1.foo(); |
| h1.bar(2); |
| } |
| } |
| |
| class Partner { |
| boolean isAlive() { return true; } |
| void foo() { System.out.println("foo"); } |
| void bar(int x) { System.out.println("bar " + x); } |
| } |
| |
| aspect HandleLiveness { |
| before(Handle handle): target(handle) && call(public * *(..)) { |
| if ( handle.partner == null || !handle.partner.isAlive() ) { |
| throw new DeadPartnerException(); |
| } |
| } |
| } |
| |
| class DeadPartnerException extends RuntimeException {} |
| </pre></div></div><div class="sect1"><a name="language-advice"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-advice"></a>Advice</h2></div></div><p> |
| Advice defines pieces of aspect implementation that execute at |
| well-defined points in the execution of the program. Those points can |
| be given either by named pointcuts (like the ones you've seen above) |
| or by anonymous pointcuts. Here is an example of an advice on a named |
| pointcut: |
| </p><pre class="programlisting"> |
| pointcut setter(Point p1, int newval): target(p1) && args(newval) |
| (call(void setX(int) || |
| call(void setY(int))); |
| |
| before(Point p1, int newval): setter(p1, newval) { |
| System.out.println("About to set something in " + p1 + |
| " to the new value " + newval); |
| } |
| </pre><p> |
| And here is exactly the same example, but using an anonymous |
| pointcut: |
| </p><pre class="programlisting"> |
| before(Point p1, int newval): target(p1) && args(newval) |
| (call(void setX(int)) || |
| call(void setY(int))) { |
| System.out.println("About to set something in " + p1 + |
| " to the new value " + newval); |
| } |
| </pre><p> |
| Here are examples of the different advice: |
| </p><p> |
| This before advice runs just before the join points picked out by the |
| (anonymous) pointcut: |
| </p><pre class="programlisting"> |
| before(Point p, int x): target(p) && args(x) && call(void setX(int)) { |
| if (!p.assertX(x)) return; |
| } |
| </pre><p> |
| This after advice runs just after each join point picked out by the |
| (anonymous) pointcut, regardless of whether it returns normally or throws |
| an exception: |
| </p><pre class="programlisting"> |
| after(Point p, int x): target(p) && args(x) && call(void setX(int)) { |
| if (!p.assertX(x)) throw new PostConditionViolation(); |
| } |
| </pre><p> |
| This after returning advice runs just after each join point picked |
| out by the (anonymous) pointcut, but only if it returns normally. |
| The return value can be accessed, and is named <tt>x</tt> |
| here. After the advice runs, the return value is returned: |
| </p><pre class="programlisting"> |
| after(Point p) returning(int x): target(p) && call(int getX()) { |
| System.out.println("Returning int value " + x + " for p = " + p); |
| } |
| </pre><p> |
| This after throwing advice runs just after each join point picked out by |
| the (anonymous) pointcut, but only when it throws an exception of type |
| <tt>Exception</tt>. Here the exception value can be accessed |
| with the name <tt>e</tt>. The advice re-raises the exception |
| after it's done: |
| </p><pre class="programlisting"> |
| after() throwing(Exception e): target(Point) && call(void setX(int)) { |
| System.out.println(e); |
| } |
| </pre><p> |
| This around advice traps the execution of the join point; it runs |
| <span class="emphasis"><i>instead</i></span> of the join point. The original action |
| associated with the join point can be invoked through the special |
| <tt>proceed</tt> call: |
| </p><pre class="programlisting"> |
| void around(Point p, int x): target(p) |
| && args(x) |
| && call(void setX(int)) { |
| if (p.assertX(x)) proceed(p, x); |
| p.releaseResources(); |
| } |
| </pre></div><div class="sect1"><a name="language-interType"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-interType"></a>Inter-type declarations</h2></div></div><p> |
| Aspects can declare members (fields, methods, and constructors) that |
| are owned by other types. These are called inter-type members. |
| Aspects can also declare that other types implement new interfaces or |
| extend a new class. Here are examples of some such inter-type |
| declarations: |
| </p><p> |
| This declares that each <tt>Server</tt> has a |
| <tt>boolean</tt> field named <tt>disabled</tt>, |
| initialized to <tt>false</tt>: |
| |
| <pre class="programlisting"> |
| private boolean Server.disabled = false; |
| </pre> |
| |
| It is declared <tt>private</tt>, which means that it is |
| private <span class="emphasis"><i>to the aspect</i></span>: only code in the aspect |
| can see the field. And even if <tt>Server</tt> has |
| another private field named <tt>disabled</tt> (declared in |
| <tt>Server</tt> or in another aspect) there won't be a name |
| collision, since no reference to <tt>disabled</tt> will be |
| ambiguous. |
| </p><p> |
| This declares that each <tt>Point</tt> has an |
| <tt>int</tt> method named <tt>getX</tt> with no |
| arguments that returns whatever <tt>this.x</tt> is: |
| |
| <pre class="programlisting"> |
| public int Point.getX() { return this.x; } |
| </pre> |
| |
| Inside the body, <tt>this</tt> is the |
| <tt>Point</tt> object currently executing. Because the |
| method is publically declared any code can call it, but if there is |
| some other <tt>Point.getX()</tt> declared there will be a |
| compile-time conflict. |
| </p><p> |
| This publically declares a two-argument constructor for |
| <tt>Point</tt>: |
| |
| <pre class="programlisting"> |
| public Point.new(int x, int y) { this.x = x; this.y = y; } |
| </pre> |
| |
| </p><p> |
| This publicly declares that each <tt>Point</tt> has an |
| <tt>int</tt> field named <tt>x</tt>, initialized |
| to zero: |
| |
| <pre class="programlisting"> |
| public int Point.x = 0; |
| </pre> |
| |
| Because this is publically declared, it is an error if |
| <tt>Point</tt> already has a field named |
| <tt>x</tt> (defined by <tt>Point</tt> or by |
| another aspect). |
| </p><p> |
| This declares that the <tt>Point</tt> class implements the |
| <tt>Comparable</tt> interface: |
| |
| <pre class="programlisting"> |
| declare parents: Point implements Comparable; |
| </pre> |
| |
| Of course, this will be an error unless <tt>Point</tt> |
| defines the methods required by <tt>Comparable</tt>. |
| </p><p> |
| This declares that the <tt>Point</tt> class extends the |
| <tt>GeometricObject</tt> class. |
| |
| <pre class="programlisting"> |
| declare parents: Point extends GeometricObject; |
| </pre> |
| </p><p> |
| An aspect can have several inter-type declarations. For example, the |
| following declarations |
| |
| <pre class="programlisting"> |
| public String Point.name; |
| public void Point.setName(String name) { this.name = name; } |
| </pre> |
| |
| publicly declare that Point has both a String field |
| <tt>name</tt> and a <tt>void</tt> method |
| <tt>setName(String)</tt> (which refers to the |
| <tt>name</tt> field declared by the aspect). |
| </p><p> |
| An inter-type member can only have one target type, but often you may |
| wish to declare the same member on more than one type. This can be |
| done by using an inter-type member in combination with a private |
| interface: |
| |
| <pre class="programlisting"> |
| aspect A { |
| private interface HasName {} |
| declare parents: (Point || Line || Square) implements HasName; |
| |
| private String HasName.name; |
| public String HasName.getName() { return name; } |
| } |
| </pre> |
| |
| This declares a marker interface <tt>HasName</tt>, and also declares that any |
| type that is either <tt>Point</tt>, |
| <tt>Line</tt>, or <tt>Square</tt> implements that |
| interface. It also privately declares that all <tt>HasName</tt> |
| object have a <tt>String</tt> field called |
| <tt>name</tt>, and publically declares that all |
| <tt>HasName</tt> objects have a <tt>String</tt> |
| method <tt>getName()</tt> (which refers to the privately |
| declared <tt>name</tt> field). |
| </p><p> |
| As you can see from the above example, an aspect can declare that |
| interfaces have fields and methods, even non-constant fields and |
| methods with bodies. |
| </p><div class="sect2"><a name="inter-type-scope"></a><div class="titlepage"><div><h3 class="title"><a name="inter-type-scope"></a>Inter-type Scope</h3></div></div><p> |
| AspectJ allows private and package-protected (default) inter-type declarations in |
| addition to public inter-type declarations. Private means private in |
| relation to the aspect, not necessarily the target type. So, if an |
| aspect makes a private inter-type declaration of a field |
| |
| <pre class="programlisting"> |
| private int Foo.x; |
| </pre> |
| |
| Then code in the aspect can refer to <tt>Foo</tt>'s |
| <tt>x</tt> field, but nobody else can. Similarly, if an |
| aspect makes a package-protected introduction, |
| </p><pre class="programlisting"> |
| int Foo.x; |
| </pre><p> |
| then everything in the aspect's package (which may or may not be |
| <tt>Foo</tt>'s package) can access <tt>x</tt>. |
| </p></div><div class="sect2"><a name="example-pointassertions"></a><div class="titlepage"><div><h3 class="title"><a name="example-pointassertions"></a>Example: <tt>PointAssertions</tt></h3></div></div><p> |
| The example below consists of one class and one aspect. The aspect |
| privately declares the assertion methods of |
| <tt>Point</tt>, <tt>assertX</tt> and |
| <tt>assertY</tt>. It also guards calls to |
| <tt>setX</tt> and <tt>setY</tt> with calls to |
| these assertion methods. The assertion methods are declared |
| privately because other parts of the program (including the code in |
| <tt>Point</tt>) have no business accessing the assert |
| methods. Only the code inside of the aspect can call those |
| methods. |
| </p><pre class="programlisting"> |
| class Point { |
| int x, y; |
| |
| public void setX(int x) { this.x = x; } |
| public void setY(int y) { this.y = y; } |
| |
| public static void main(String[] args) { |
| Point p = new Point(); |
| p.setX(3); p.setY(333); |
| } |
| } |
| |
| aspect PointAssertions { |
| |
| private boolean Point.assertX(int x) { |
| return (x <= 100 && x >= 0); |
| } |
| private boolean Point.assertY(int y) { |
| return (y <= 100 && y >= 0); |
| } |
| |
| before(Point p, int x): target(p) && args(x) && call(void setX(int)) { |
| if (!p.assertX(x)) { |
| System.out.println("Illegal value for x"); return; |
| } |
| } |
| before(Point p, int y): target(p) && args(y) && call(void setY(int)) { |
| if (!p.assertY(y)) { |
| System.out.println("Illegal value for y"); return; |
| } |
| } |
| } |
| </pre></div></div><div class="sect1"><a name="language-thisJoinPoint"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="language-thisJoinPoint"></a>thisJoinPoint</h2></div></div><p> |
| AspectJ provides a special reference variable, |
| <tt>thisJoinPoint</tt>, that contains reflective |
| information about the current join point for the advice to use. The |
| <tt>thisJoinPoint</tt> variable can only be used in the |
| context of advice, just like <tt>this</tt> can only be used |
| in the context of non-static methods and variable initializers. In |
| advice, <tt>thisJoinPoint</tt> is an object of type <a href="../api/org/aspectj/lang/JoinPoint.html" target="_top"><tt>org.aspectj.lang.JoinPoint</tt></a>. |
| </p><p> |
| One way to use it is simply to print it out. Like all Java objects, |
| <tt>thisJoinPoint</tt> has a <tt>toString()</tt> |
| method that makes quick-and-dirty tracing easy: |
| </p><pre class="programlisting"> |
| class TraceNonStaticMethods { |
| before(Point p): target(p) && call(* *(..)) { |
| System.out.println("Entering " + thisJoinPoint + " in " + p); |
| } |
| } |
| </pre><p> |
| The type of <tt>thisJoinPoint</tt> includes a rich |
| reflective class hierarchy of signatures, and can be used to access |
| both static and dynamic information about join points such as the |
| arguments of the join point: |
| |
| <pre class="programlisting"> |
| thisJoinPoint.getArgs() |
| </pre> |
| |
| In addition, it holds an object consisting of all the static |
| information about the join point such as corresponding line number |
| and static signature: |
| |
| <pre class="programlisting"> |
| thisJoinPoint.getStaticPart() |
| </pre> |
| |
| If you only need the static information about the join point, you may |
| access the static part of the join point directly with the special |
| variable <tt>thisJoinPointStaticPart</tt>. Using |
| <tt>thisJoinPointStaticPart</tt> will avoid the run-time |
| creation of the join point object that may be necessary when using |
| <tt>thisJoinPoint</tt> directly. |
| </p><p>It is always the case that |
| </p><pre class="programlisting"> |
| thisJoinPointStaticPart == thisJoinPoint.getStaticPart() |
| |
| thisJoinPoint.getKind() == thisJoinPointStaticPart.getKind() |
| thisJoinPoint.getSignature() == thisJoinPointStaticPart.getSignature() |
| thisJoinPoint.getSourceLocation() == thisJoinPointStaticPart.getSourceLocation() |
| </pre><p> |
| One more reflective variable is available: |
| <tt>thisEnclosingJoinPointStaticPart</tt>. This, like |
| <tt>thisJoinPointStaticPart</tt>, only holds the static |
| part of a join point, but it is not the current but the enclosing |
| join point. So, for example, it is possible to print out the calling |
| source location (if available) with |
| </p><pre class="programlisting"> |
| before() : execution (* *(..)) { |
| System.err.println(thisEnclosingJoinPointStaticPart.getSourceLocation()) |
| } |
| </pre></div></div><div class="chapter"><div class="titlepage"><div><h2 class="title"><a name="examples"></a>Chapter 3. Examples</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#examples-intro">Introduction</a></dt><dt><a href="#examples-howto">Obtaining, Compiling and Running the Examples</a></dt><dt><a href="#examples-basic">Basic Techniques</a></dt><dd><dl><dt><a href="#examples-joinPoints">Join Points and <tt>thisJoinPoint</tt></a></dt><dt><a href="#examples-roles">Roles and Views</a></dt></dl></dd><dt><a href="#examples-development">Development Aspects</a></dt><dd><dl><dt><a href="#tracing-using-aspects">Tracing using aspects</a></dt></dl></dd><dt><a href="#examples-production">Production Aspects</a></dt><dd><dl><dt><a href="#a-bean-aspect">A Bean Aspect</a></dt><dt><a href="#the-subject-observer-protocol">The Subject/Observer Protocol</a></dt><dt><a href="#a-simple-telecom-simulation">A Simple Telecom Simulation</a></dt></dl></dd><dt><a href="#examples-reusable">Reusable Aspects</a></dt><dd><dl><dt><a href="#tracing-using-aspects-revisited">Tracing using Aspects, Revisited</a></dt></dl></dd></dl></div><div class="sect1"><a name="examples-intro"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="examples-intro"></a>Introduction</h2></div></div><p> |
| This chapter consists entirely of examples of AspectJ use. |
| </p><p>The examples can be grouped into four categories:</p><table class="simplelist" border="0" summary="Simple list"><tr><td><span class="bold"><b>technique</b></span></td><td>Examples which illustrate how to use one or more features of the |
| language. </td></tr><tr><td><span class="bold"><b>development</b></span></td><td>Examples of using AspectJ during the development phase of a |
| project. </td></tr><tr><td><span class="bold"><b>production</b></span></td><td>Examples of using AspectJ to provide functionality in an |
| application. </td></tr><tr><td><span class="bold"><b>reusable</b></span></td><td>Examples of reuse of aspects and pointcuts.</td></tr></table></div><div class="sect1"><a name="examples-howto"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="examples-howto"></a>Obtaining, Compiling and Running the Examples</h2></div></div><p> |
| The examples source code is part of the AspectJ distribution which may be |
| downloaded from the AspectJ project page ( <a href="http://eclipse.org/aspectj" target="_top">http://eclipse.org/aspectj</a> ). |
| </p><p> |
| Compiling most examples is straightforward. Go the |
| <tt><i><tt>InstallDir</tt></i>/examples</tt> |
| directory, and look for a <tt>.lst</tt> file in one of |
| the example subdirectories. Use the <tt>-arglist</tt> |
| option to <tt>ajc</tt> to compile the example. For |
| instance, to compile the telecom example with billing, type |
| </p><pre class="programlisting"> |
| ajc -argfile telecom/billing.lst |
| </pre><p> |
| To run the examples, your classpath must include the AspectJ run-time |
| Java archive (<tt>aspectjrt.jar</tt>). You may either set the |
| <tt>CLASSPATH</tt> environment variable or use the |
| <tt>-classpath</tt> command line option to the Java |
| interpreter: |
| </p><pre class="programlisting"> |
| (In Unix use a : in the CLASSPATH) |
| java -classpath ".:<i><tt>InstallDir</tt></i>/lib/aspectjrt.jar" telecom.billingSimulation |
| </pre><pre class="programlisting"> |
| (In Windows use a ; in the CLASSPATH) |
| java -classpath ".;<i><tt>InstallDir</tt></i>/lib/aspectjrt.jar" telecom.billingSimulation |
| </pre></div><div class="sect1"><a name="examples-basic"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="examples-basic"></a>Basic Techniques</h2></div></div><p> |
| This section presents two basic techniques of using AspectJ, one each |
| from the two fundamental ways of capturing crosscutting concerns: |
| with dynamic join points and advice, and with static |
| introduction. Advice changes an application's behavior. Introduction |
| changes both an application's behavior and its structure. |
| </p><p> |
| The first example, <a href="#examples-joinPoints" title="Join Points and thisJoinPoint">the section called “Join Points and <tt>thisJoinPoint</tt>”</a>, is about |
| gathering and using information about the join point that has |
| triggered some advice. The second example, <a href="#examples-roles" title="Roles and Views">the section called “Roles and Views”</a>, concerns a crosscutting view of an |
| existing class hierarchy. </p><div class="sect2"><a name="examples-joinPoints"></a><div class="titlepage"><div><h3 class="title"><a name="examples-joinPoints"></a>Join Points and <tt>thisJoinPoint</tt></h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/tjp</tt>.) |
| </p><p> |
| A join point is some point in the execution of a program together |
| with a view into the execution context when that point occurs. Join |
| points are picked out by pointcuts. When a program reaches a join |
| point, advice on that join point may run in addition to (or instead |
| of) the join point itself. |
| </p><p> |
| When using a pointcut that picks out join points of a single kind |
| by name, typicaly the the advice will know exactly what kind of |
| join point it is associated with. The pointcut may even publish |
| context about the join point. Here, for example, since the only |
| join points picked out by the pointcut are calls of a certain |
| method, we can get the target value and one of the argument values |
| of the method calls directly. |
| </p><pre class="programlisting"> |
| before(Point p, int x): target(p) |
| && args(x) |
| && call(void setX(int)) { |
| if (!p.assertX(x)) { |
| System.out.println("Illegal value for x"); return; |
| } |
| } |
| </pre><p> |
| But sometimes the shape of the join point is not so clear. For |
| instance, suppose a complex application is being debugged, and we |
| want to trace when any method of some class is executed. The |
| pointcut |
| </p><pre class="programlisting"> |
| pointcut execsInProblemClass(): within(ProblemClass) |
| && execution(* *(..)); |
| </pre><p> |
| will pick out each execution join point of every method defined |
| within <tt>ProblemClass</tt>. Since advice executes |
| at each join point picked out by the pointcut, we can reasonably |
| ask which join point was reached. |
| </p><p> |
| Information about the join point that was matched is available to |
| advice through the special variable |
| <tt>thisJoinPoint</tt>, of type <a href="../api/org/aspectj/lang/JoinPoint.html" target="_top"><tt>org.aspectj.lang.JoinPoint</tt></a>. |
| Through this object we can access information such as</p><div class="itemizedlist"><ul compact><li><a name="d0e2074"></a> |
| the kind of join point that was matched |
| </li><li><a name="d0e2076"></a> |
| the source location of the code associated with the join point |
| </li><li><a name="d0e2078"></a> |
| normal, short and long string representations of the |
| current join point |
| </li><li><a name="d0e2080"></a> |
| the actual argument values of the join point |
| </li><li><a name="d0e2082"></a> |
| the signature of the member associated with the join point |
| </li><li><a name="d0e2084"></a>the currently executing object</li><li><a name="d0e2086"></a>the target object</li><li><a name="d0e2088"></a> |
| an object encapsulating the static information about the join |
| point. This is also available through the special variable |
| <tt>thisJoinPointStaticPart</tt>.</li></ul></div><div class="sect3"><a name="d0e2093"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2093"></a>The <tt>Demo</tt> class</h4></div></div><p>The class <tt>tjp.Demo</tt> in |
| <tt>tjp/Demo.java</tt> defines two methods |
| <tt>foo</tt> and <tt>bar</tt> with different |
| parameter lists and return types. Both are called, with suitable |
| arguments, by <tt>Demo</tt>'s |
| <tt>go</tt> method which was invoked from within its |
| <tt>main</tt> method. |
| </p><pre class="programlisting"> |
| public class Demo { |
| static Demo d; |
| |
| public static void main(String[] args){ |
| new Demo().go(); |
| } |
| |
| void go(){ |
| d = new Demo(); |
| d.foo(1,d); |
| System.out.println(d.bar(new Integer(3))); |
| } |
| |
| void foo(int i, Object o){ |
| System.out.println("Demo.foo(" + i + ", " + o + ")\n"); |
| } |
| |
| String bar (Integer j){ |
| System.out.println("Demo.bar(" + j + ")\n"); |
| return "Demo.bar(" + j + ")"; |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e2124"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2124"></a>The <tt>GetInfo</tt> aspect</h4></div></div><p> |
| This aspect uses around advice to intercept the execution of |
| methods <tt>foo</tt> and <tt>bar</tt> in |
| <tt>Demo</tt>, and prints out information garnered |
| from <tt>thisJoinPoint</tt> to the console. |
| </p><pre class="programlisting"> |
| aspect GetInfo { |
| |
| static final void println(String s){ System.out.println(s); } |
| |
| pointcut goCut(): cflow(this(Demo) && execution(void go())); |
| |
| pointcut demoExecs(): within(Demo) && execution(* *(..)); |
| |
| Object around(): demoExecs() && !execution(* go()) && goCut() { |
| println("Intercepted message: " + |
| thisJoinPointStaticPart.getSignature().getName()); |
| println("in class: " + |
| thisJoinPointStaticPart.getSignature().getDeclaringType().getName()); |
| printParameters(thisJoinPoint); |
| println("Running original method: \n" ); |
| Object result = proceed(); |
| println(" result: " + result ); |
| return result; |
| } |
| |
| static private void printParameters(JoinPoint jp) { |
| println("Arguments: " ); |
| Object[] args = jp.getArgs(); |
| String[] names = ((CodeSignature)jp.getSignature()).getParameterNames(); |
| Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes(); |
| for (int i = 0; i < args.length; i++) { |
| println(" " + i + ". " + names[i] + |
| " : " + types[i].getName() + |
| " = " + args[i]); |
| } |
| } |
| } |
| </pre><div class="sect4"><a name="d0e2146"></a><div class="titlepage"><div><h5 class="title"><a name="d0e2146"></a>Defining the scope of a pointcut</h5></div></div><p>The pointcut <tt>goCut</tt> is defined as |
| |
| <pre class="programlisting"> |
| cflow(this(Demo)) && execution(void go()) |
| </pre> |
| |
| so that only executions made in the control flow of |
| <tt>Demo.go</tt> are intercepted. The control flow |
| from the method <tt>go</tt> includes the execution of |
| <tt>go</tt> itself, so the definition of the around |
| advice includes <tt>!execution(* go())</tt> to |
| exclude it from the set of executions advised. </p></div><div class="sect4"><a name="d0e2169"></a><div class="titlepage"><div><h5 class="title"><a name="d0e2169"></a>Printing the class and method name</h5></div></div><p> |
| The name of the method and that method's defining class are |
| available as parts of the <a href="../api/org/aspectj/lang/Signature.html" target="_top">org.aspectj.lang.Signature</a> |
| object returned by calling <tt>getSignature()</tt> on |
| either <tt>thisJoinPoint</tt> or |
| <tt>thisJoinPointStaticPart</tt>. |
| </p></div><div class="sect4"><a name="d0e2186"></a><div class="titlepage"><div><h5 class="title"><a name="d0e2186"></a>Printing the parameters</h5></div></div><p> |
| The static portions of the parameter details, the name and |
| types of the parameters, can be accessed through the <a href="../api/org/aspectj/lang/reflect/CodeSignature.html" target="_top"><tt>org.aspectj.lang.reflect.CodeSignature</tt></a> |
| associated with the join point. All execution join points have code |
| signatures, so the cast to <tt>CodeSignature</tt> |
| cannot fail. </p><p> |
| The dynamic portions of the parameter details, the actual |
| values of the parameters, are accessed directly from the |
| execution join point object. |
| </p></div></div></div><div class="sect2"><a name="examples-roles"></a><div class="titlepage"><div><h3 class="title"><a name="examples-roles"></a>Roles and Views</h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/introduction</tt>.) |
| </p><p> |
| Like advice, inter-type declarations are members of an aspect. They |
| declare members that act as if they were defined on another class. |
| Unlike advice, inter-type declarations affect not only the behavior |
| of the application, but also the structural relationship between an |
| application's classes. |
| </p><p> |
| This is crucial: Publically affecting the class structure of an |
| application makes these modifications available to other components |
| of the application. |
| </p><p> |
| Aspects can declare inter-type |
| |
| <div class="itemizedlist"><ul compact><li><a name="d0e2218"></a>fields</li><li><a name="d0e2220"></a>methods</li><li><a name="d0e2222"></a>constructors</li></ul></div> |
| |
| and can also declare that target types |
| |
| <div class="itemizedlist"><ul compact><li><a name="d0e2226"></a>implement new interfaces</li><li><a name="d0e2228"></a>extend new classes</li></ul></div> |
| </p><p> |
| This example provides three illustrations of the use of inter-type |
| declarations to encapsulate roles or views of a class. The class |
| our aspect will be dealing with, <tt>Point</tt>, is a |
| simple class with rectangular and polar coordinates. Our inter-type |
| declarations will make the class <tt>Point</tt>, in |
| turn, cloneable, hashable, and comparable. These facilities are |
| provided by AspectJ without having to modify the code for the class |
| <tt>Point</tt>. |
| </p><div class="sect3"><a name="d0e2242"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2242"></a>The <tt>Point</tt> class</h4></div></div><p>The <tt>Point</tt> class defines geometric points |
| whose interface includes polar and rectangular coordinates, plus some |
| simple operations to relocate points. <tt>Point</tt>'s |
| implementation has attributes for both its polar and rectangular |
| coordinates, plus flags to indicate which currently reflect the |
| position of the point. Some operations cause the polar coordinates to |
| be updated from the rectangular, and some have the opposite effect. |
| This implementation, which is in intended to give the minimum number |
| of conversions between coordinate systems, has the property that not |
| all the attributes stored in a <tt>Point</tt> object |
| are necessary to give a canonical representation such as might be |
| used for storing, comparing, cloning or making hash codes from |
| points. Thus the aspects, though simple, are not totally trivial. |
| </p><p> |
| The diagram below gives an overview of the aspects and their |
| interaction with the class <tt>Point</tt>.</p><p> |
| <span class="inlinemediaobject"><img src="aspects.gif"></span> |
| </p><p></p></div><div class="sect3"><a name="d0e2271"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2271"></a>The <tt>CloneablePoint</tt> aspect</h4></div></div><p> |
| This first aspect is responsible for |
| <tt>Point</tt>'s implementation of the |
| <tt>Cloneable</tt> interface. It declares that |
| <tt>Point implements Cloneable</tt> with a |
| <tt>declare parents</tt> form, and also publically |
| declares a specialized <tt>Point</tt>'s |
| <tt>clone()</tt> method. In Java, all objects inherit |
| the method <tt>clone</tt> from the class |
| <tt>Object</tt>, but an object is not cloneable |
| unless its class also implements the interface |
| <tt>Cloneable</tt>. In addition, classes |
| frequently have requirements over and above the simple |
| bit-for-bit copying that <tt>Object.clone</tt> does. In |
| our case, we want to update a <tt>Point</tt>'s |
| coordinate systems before we actually clone the |
| <tt>Point</tt>. So our aspect makes sure that |
| <tt>Point</tt> overrides |
| <tt>Object.clone</tt> with a new method that does what |
| we want. |
| </p><p> |
| We also define a test <tt>main</tt> method in the |
| aspect for convenience. |
| </p><pre class="programlisting"> |
| public aspect CloneablePoint { |
| |
| declare parents: Point implements Cloneable; |
| |
| public Object Point.clone() throws CloneNotSupportedException { |
| // we choose to bring all fields up to date before cloning. |
| makeRectangular(); |
| makePolar(); |
| return super.clone(); |
| } |
| |
| public static void main(String[] args){ |
| Point p1 = new Point(); |
| Point p2 = null; |
| |
| p1.setPolar(Math.PI, 1.0); |
| try { |
| p2 = (Point)p1.clone(); |
| } catch (CloneNotSupportedException e) {} |
| System.out.println("p1 =" + p1 ); |
| System.out.println("p2 =" + p2 ); |
| |
| p1.rotate(Math.PI / -2); |
| System.out.println("p1 =" + p1 ); |
| System.out.println("p2 =" + p2 ); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e2328"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2328"></a>The <tt>ComparablePoint</tt> aspect</h4></div></div><p> |
| <tt>ComparablePoint</tt> is responsible for |
| <tt>Point</tt>'s implementation of the |
| <tt>Comparable</tt> interface. </p><p> |
| The interface <tt>Comparable</tt> defines the |
| single method <tt>compareTo</tt> which can be use to define |
| a natural ordering relation among the objects of a class that |
| implement it. |
| </p><p> |
| <tt>ComparablePoint</tt> uses <tt>declare |
| parents</tt> to declare that <tt>Point implements |
| Comparable</tt>, and also publically declares the |
| appropriate <tt>compareTo(Object)</tt> method: A |
| <tt>Point</tt> <tt>p1</tt> is said to be |
| less than another <tt>Point</tt><tt> |
| p2</tt> if <tt>p1</tt> is closer to the |
| origin. |
| </p><p> |
| We also define a test <tt>main</tt> method in the |
| aspect for convenience. |
| </p><pre class="programlisting"> |
| public aspect ComparablePoint { |
| |
| declare parents: Point implements Comparable; |
| |
| public int Point.compareTo(Object o) { |
| return (int) (this.getRho() - ((Point)o).getRho()); |
| } |
| |
| public static void main(String[] args){ |
| Point p1 = new Point(); |
| Point p2 = new Point(); |
| |
| System.out.println("p1 =?= p2 :" + p1.compareTo(p2)); |
| |
| p1.setRectangular(2,5); |
| p2.setRectangular(2,5); |
| System.out.println("p1 =?= p2 :" + p1.compareTo(p2)); |
| |
| p2.setRectangular(3,6); |
| System.out.println("p1 =?= p2 :" + p1.compareTo(p2)); |
| |
| p1.setPolar(Math.PI, 4); |
| p2.setPolar(Math.PI, 4); |
| System.out.println("p1 =?= p2 :" + p1.compareTo(p2)); |
| |
| p1.rotate(Math.PI / 4.0); |
| System.out.println("p1 =?= p2 :" + p1.compareTo(p2)); |
| |
| p1.offset(1,1); |
| System.out.println("p1 =?= p2 :" + p1.compareTo(p2)); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e2388"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2388"></a>The <tt>HashablePoint</tt> aspect</h4></div></div><p> |
| Our third aspect is responsible for <tt>Point</tt>'s |
| overriding of <tt>Object</tt>'s |
| <tt>equals</tt> and <tt>hashCode</tt> methods |
| in order to make <tt>Point</tt>s hashable. |
| </p><p> |
| The method <tt>Object.hashCode</tt> returns an |
| integer, suitable for use as a hash table key. It is not required |
| that two objects which are not equal (according to the |
| <tt>equals</tt> method) return different integer |
| results from <tt>hashCode</tt> but it can |
| improve performance when the integer is used as a key into a |
| data structure. However, any two objects which are equal |
| must return the same integer value from a call to |
| <tt>hashCode</tt>. Since the default implementation |
| of <tt>Object.equals</tt> returns <tt>true</tt> |
| only when two objects are identical, we need to redefine both |
| <tt>equals</tt> and <tt>hashCode</tt> to work |
| correctly with objects of type <tt>Point</tt>. For |
| example, we want two <tt>Point</tt> objects to test |
| equal when they have the same <tt>x</tt> and |
| <tt>y</tt> values, or the same <tt>rho</tt> and |
| <tt>theta</tt> values, not just when they refer to the same |
| object. We do this by overriding the methods |
| <tt>equals</tt> and <tt>hashCode</tt> in the |
| class <tt>Point</tt>. |
| </p><p> |
| So <tt>HashablePoint</tt> declares |
| <tt>Point</tt>'s <tt>hashCode</tt> and |
| <tt>equals</tt> methods, using |
| <tt>Point</tt>'s rectangular coordinates to |
| generate a hash code and to test for equality. The |
| <tt>x</tt> and <tt>y</tt> coordinates are |
| obtained using the appropriate get methods, which ensure the |
| rectangular coordinates are up-to-date before returning their |
| values. |
| </p><p> |
| And again, we supply a <tt>main</tt> method in the |
| aspect for testing. |
| </p><pre class="programlisting"> |
| public aspect HashablePoint { |
| |
| public int Point.hashCode() { |
| return (int) (getX() + getY() % Integer.MAX_VALUE); |
| } |
| |
| public boolean Point.equals(Object o) { |
| if (o == this) { return true; } |
| if (!(o instanceof Point)) { return false; } |
| Point other = (Point)o; |
| return (getX() == other.getX()) && (getY() == other.getY()); |
| } |
| |
| public static void main(String[] args) { |
| Hashtable h = new Hashtable(); |
| Point p1 = new Point(); |
| |
| p1.setRectangular(10, 10); |
| Point p2 = new Point(); |
| |
| p2.setRectangular(10, 10); |
| |
| System.out.println("p1 = " + p1); |
| System.out.println("p2 = " + p2); |
| System.out.println("p1.hashCode() = " + p1.hashCode()); |
| System.out.println("p2.hashCode() = " + p2.hashCode()); |
| |
| h.put(p1, "P1"); |
| System.out.println("Got: " + h.get(p2)); |
| } |
| } |
| </pre></div></div></div><div class="sect1"><a name="examples-development"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="examples-development"></a>Development Aspects</h2></div></div><div class="sect2"><a name="tracing-using-aspects"></a><div class="titlepage"><div><h3 class="title"><a name="tracing-using-aspects"></a>Tracing using aspects</h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/tracing</tt>.) |
| </p><p> |
| Writing a class that provides tracing functionality is easy: a |
| couple of functions, a boolean flag for turning tracing on and |
| off, a choice for an output stream, maybe some code for |
| formatting the output -- these are all elements that |
| <tt>Trace</tt> classes have been known to |
| have. <tt>Trace</tt> classes may be highly |
| sophisticated, too, if the task of tracing the execution of a |
| program demands it. |
| </p><p> |
| But developing the support for tracing is just one part of the |
| effort of inserting tracing into a program, and, most likely, not |
| the biggest part. The other part of the effort is calling the |
| tracing functions at appropriate times. In large systems, this |
| interaction with the tracing support can be overwhelming. Plus, |
| tracing is one of those things that slows the system down, so |
| these calls should often be pulled out of the system before the |
| product is shipped. For these reasons, it is not unusual for |
| developers to write ad-hoc scripting programs that rewrite the |
| source code by inserting/deleting trace calls before and after |
| the method bodies. |
| </p><p> |
| AspectJ can be used for some of these tracing concerns in a less |
| ad-hoc way. Tracing can be seen as a concern that crosscuts the |
| entire system and as such is amenable to encapsulation in an |
| aspect. In addition, it is fairly independent of what the system |
| is doing. Therefore tracing is one of those kind of system |
| aspects that can potentially be plugged in and unplugged without |
| any side-effects in the basic functionality of the system. |
| </p><div class="sect3"><a name="d0e2521"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2521"></a>An Example Application</h4></div></div><p> |
| Throughout this example we will use a simple application that |
| contains only four classes. The application is about shapes. The |
| <tt>TwoDShape</tt> class is the root of the shape |
| hierarchy: |
| </p><pre class="programlisting"> |
| public abstract class TwoDShape { |
| protected double x, y; |
| protected TwoDShape(double x, double y) { |
| this.x = x; this.y = y; |
| } |
| public double getX() { return x; } |
| public double getY() { return y; } |
| public double distance(TwoDShape s) { |
| double dx = Math.abs(s.getX() - x); |
| double dy = Math.abs(s.getY() - y); |
| return Math.sqrt(dx*dx + dy*dy); |
| } |
| public abstract double perimeter(); |
| public abstract double area(); |
| public String toString() { |
| return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") "); |
| } |
| } |
| </pre><p> |
| <tt>TwoDShape</tt> has two subclasses, |
| <tt>Circle</tt> and <tt>Square</tt>: |
| </p><pre class="programlisting"> |
| public class Circle extends TwoDShape { |
| protected double r; |
| public Circle(double x, double y, double r) { |
| super(x, y); this.r = r; |
| } |
| public Circle(double x, double y) { this( x, y, 1.0); } |
| public Circle(double r) { this(0.0, 0.0, r); } |
| public Circle() { this(0.0, 0.0, 1.0); } |
| public double perimeter() { |
| return 2 * Math.PI * r; |
| } |
| public double area() { |
| return Math.PI * r*r; |
| } |
| public String toString() { |
| return ("Circle radius = " + String.valueOf(r) + super.toString()); |
| } |
| } |
| </pre><pre class="programlisting"> |
| public class Square extends TwoDShape { |
| protected double s; // side |
| public Square(double x, double y, double s) { |
| super(x, y); this.s = s; |
| } |
| public Square(double x, double y) { this( x, y, 1.0); } |
| public Square(double s) { this(0.0, 0.0, s); } |
| public Square() { this(0.0, 0.0, 1.0); } |
| public double perimeter() { |
| return 4 * s; |
| } |
| public double area() { |
| return s*s; |
| } |
| public String toString() { |
| return ("Square side = " + String.valueOf(s) + super.toString()); |
| } |
| } |
| </pre><p> |
| To run this application, compile the classes. You can do it with or |
| without ajc, the AspectJ compiler. If you've installed AspectJ, go |
| to the directory |
| <tt><i><tt>InstallDir</tt></i>/examples</tt> |
| and type: |
| </p><pre class="programlisting"> |
| ajc -argfile tracing/notrace.lst |
| </pre><p>To run the program, type</p><pre class="programlisting"> |
| java tracing.ExampleMain |
| </pre><p>(we don't need anything special on the classpath since this is pure |
| Java code). You should see the following output:</p><pre class="programlisting"> |
| c1.perimeter() = 12.566370614359172 |
| c1.area() = 12.566370614359172 |
| s1.perimeter() = 4.0 |
| s1.area() = 1.0 |
| c2.distance(c1) = 4.242640687119285 |
| s1.distance(c1) = 2.23606797749979 |
| s1.toString(): Square side = 1.0 @ (1.0, 2.0) |
| </pre></div><div class="sect3"><a name="d0e2563"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2563"></a>Tracing—Version 1</h4></div></div><p> |
| In a first attempt to insert tracing in this application, we will |
| start by writing a <tt>Trace</tt> class that is |
| exactly what we would write if we didn't have aspects. The |
| implementation is in <tt>version1/Trace.java</tt>. Its |
| public interface is: |
| </p><pre class="programlisting"> |
| public class Trace { |
| public static int TRACELEVEL = 0; |
| public static void initStream(PrintStream s) {...} |
| public static void traceEntry(String str) {...} |
| public static void traceExit(String str) {...} |
| } |
| </pre><p> |
| If we didn't have AspectJ, we would have to insert calls to |
| <tt>traceEntry</tt> and <tt>traceExit</tt> in |
| all methods and constructors we wanted to trace, and to initialize |
| <tt>TRACELEVEL</tt> and the stream. If we wanted to trace |
| all the methods and constructors in our example, that would amount |
| to around 40 calls, and we would hope we had not forgotten any |
| method. But we can do that more consistently and reliably with the |
| following aspect (found in |
| <tt>version1/TraceMyClasses.java</tt>): |
| </p><pre class="programlisting"> |
| aspect TraceMyClasses { |
| pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square); |
| pointcut myConstructor(): myClass() && execution(new(..)); |
| pointcut myMethod(): myClass() && execution(* *(..)); |
| |
| before (): myConstructor() { |
| Trace.traceEntry("" + thisJoinPointStaticPart.getSignature()); |
| } |
| after(): myConstructor() { |
| Trace.traceExit("" + thisJoinPointStaticPart.getSignature()); |
| } |
| |
| before (): myMethod() { |
| Trace.traceEntry("" + thisJoinPointStaticPart.getSignature()); |
| } |
| after(): myMethod() { |
| Trace.traceExit("" + thisJoinPointStaticPart.getSignature()); |
| } |
| }</pre><p> |
| This aspect performs the tracing calls at appropriate |
| times. According to this aspect, tracing is performed at the |
| entrance and exit of every method and constructor defined within |
| the shape hierarchy. |
| </p><p> |
| What is printed at before and after each of the traced join points |
| is the signature of the method executing. Since the signature is |
| static information, we can get it through |
| <tt>thisJoinPointStaticPart</tt>. |
| </p><p> |
| To run this version of tracing, go to the directory |
| <tt><i><tt>InstallDir</tt></i>/examples</tt> |
| and type: |
| </p><pre class="programlisting"> |
| ajc -argfile tracing/tracev1.lst |
| </pre><p> |
| Running the main method of |
| <tt>tracing.version1.TraceMyClasses</tt> should produce |
| the output: |
| </p><pre class="programlisting"> |
| --> tracing.TwoDShape(double, double) |
| <-- tracing.TwoDShape(double, double) |
| --> tracing.Circle(double, double, double) |
| <-- tracing.Circle(double, double, double) |
| --> tracing.TwoDShape(double, double) |
| <-- tracing.TwoDShape(double, double) |
| --> tracing.Circle(double, double, double) |
| <-- tracing.Circle(double, double, double) |
| --> tracing.Circle(double) |
| <-- tracing.Circle(double) |
| --> tracing.TwoDShape(double, double) |
| <-- tracing.TwoDShape(double, double) |
| --> tracing.Square(double, double, double) |
| <-- tracing.Square(double, double, double) |
| --> tracing.Square(double, double) |
| <-- tracing.Square(double, double) |
| --> double tracing.Circle.perimeter() |
| <-- double tracing.Circle.perimeter() |
| c1.perimeter() = 12.566370614359172 |
| --> double tracing.Circle.area() |
| <-- double tracing.Circle.area() |
| c1.area() = 12.566370614359172 |
| --> double tracing.Square.perimeter() |
| <-- double tracing.Square.perimeter() |
| s1.perimeter() = 4.0 |
| --> double tracing.Square.area() |
| <-- double tracing.Square.area() |
| s1.area() = 1.0 |
| --> double tracing.TwoDShape.distance(TwoDShape) |
| --> double tracing.TwoDShape.getX() |
| <-- double tracing.TwoDShape.getX() |
| --> double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.distance(TwoDShape) |
| c2.distance(c1) = 4.242640687119285 |
| --> double tracing.TwoDShape.distance(TwoDShape) |
| --> double tracing.TwoDShape.getX() |
| <-- double tracing.TwoDShape.getX() |
| --> double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.distance(TwoDShape) |
| s1.distance(c1) = 2.23606797749979 |
| --> String tracing.Square.toString() |
| --> String tracing.TwoDShape.toString() |
| <-- String tracing.TwoDShape.toString() |
| <-- String tracing.Square.toString() |
| s1.toString(): Square side = 1.0 @ (1.0, 2.0) |
| </pre><p> |
| When <tt>TraceMyClasses.java</tt> is not provided to |
| <b>ajc</b>, the aspect does not have any affect on the |
| system and the tracing is unplugged. |
| </p></div><div class="sect3"><a name="d0e2623"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2623"></a>Tracing—Version 2</h4></div></div><p> |
| Another way to accomplish the same thing would be to write a |
| reusable tracing aspect that can be used not only for these |
| application classes, but for any class. One way to do this is to |
| merge the tracing functionality of |
| <tt>Trace—version1</tt> with the crosscutting |
| support of <tt>TraceMyClasses—version1</tt>. We end |
| up with a <tt>Trace</tt> aspect (found in |
| <tt>version2/Trace.java</tt>) with the following public |
| interface |
| </p><pre class="programlisting"> |
| abstract aspect Trace { |
| |
| public static int TRACELEVEL = 2; |
| public static void initStream(PrintStream s) {...} |
| protected static void traceEntry(String str) {...} |
| protected static void traceExit(String str) {...} |
| abstract pointcut myClass(); |
| } |
| </pre><p> |
| In order to use it, we need to define our own subclass that knows |
| about our application classes, in |
| <tt>version2/TraceMyClasses.java</tt>: |
| </p><pre class="programlisting"> |
| public aspect TraceMyClasses extends Trace { |
| pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square); |
| |
| public static void main(String[] args) { |
| Trace.TRACELEVEL = 2; |
| Trace.initStream(System.err); |
| ExampleMain.main(args); |
| } |
| } |
| </pre><p> |
| Notice that we've simply made the pointcut |
| <tt>classes</tt>, that was an abstract pointcut in the |
| super-aspect, concrete. To run this version of tracing, go to the |
| directory <tt>examples</tt> and type: |
| </p><pre class="programlisting"> |
| ajc -argfile tracing/tracev2.lst |
| </pre><p> |
| The file tracev2.lst lists the application classes as well as this |
| version of the files Trace.java and TraceMyClasses.java. Running |
| the main method of |
| <tt>tracing.version2.TraceMyClasses</tt> should |
| output exactly the same trace information as that from version 1. |
| </p><p> |
| The entire implementation of the new <tt>Trace</tt> |
| class is: |
| </p><pre class="programlisting"> |
| abstract aspect Trace { |
| |
| // implementation part |
| |
| public static int TRACELEVEL = 2; |
| protected static PrintStream stream = System.err; |
| protected static int callDepth = 0; |
| |
| public static void initStream(PrintStream s) { |
| stream = s; |
| } |
| protected static void traceEntry(String str) { |
| if (TRACELEVEL == 0) return; |
| if (TRACELEVEL == 2) callDepth++; |
| printEntering(str); |
| } |
| protected static void traceExit(String str) { |
| if (TRACELEVEL == 0) return; |
| printExiting(str); |
| if (TRACELEVEL == 2) callDepth--; |
| } |
| private static void printEntering(String str) { |
| printIndent(); |
| stream.println("--> " + str); |
| } |
| private static void printExiting(String str) { |
| printIndent(); |
| stream.println("<-- " + str); |
| } |
| private static void printIndent() { |
| for (int i = 0; i < callDepth; i++) |
| stream.print(" "); |
| } |
| |
| // protocol part |
| |
| abstract pointcut myClass(); |
| |
| pointcut myConstructor(): myClass() && execution(new(..)); |
| pointcut myMethod(): myClass() && execution(* *(..)); |
| |
| before(): myConstructor() { |
| traceEntry("" + thisJoinPointStaticPart.getSignature()); |
| } |
| after(): myConstructor() { |
| traceExit("" + thisJoinPointStaticPart.getSignature()); |
| } |
| |
| before(): myMethod() { |
| traceEntry("" + thisJoinPointStaticPart.getSignature()); |
| } |
| after(): myMethod() { |
| traceExit("" + thisJoinPointStaticPart.getSignature()); |
| } |
| } |
| </pre><p> |
| This version differs from version 1 in several subtle ways. The |
| first thing to notice is that this <tt>Trace</tt> |
| class merges the functional part of tracing with the crosscutting |
| of the tracing calls. That is, in version 1, there was a sharp |
| separation between the tracing support (the class |
| <tt>Trace</tt>) and the crosscutting usage of it (by |
| the class <tt>TraceMyClasses</tt>). In this version |
| those two things are merged. That's why the description of this |
| class explicitly says that "Trace messages are printed before and |
| after constructors and methods are," which is what we wanted in the |
| first place. That is, the placement of the calls, in this version, |
| is established by the aspect class itself, leaving less opportunity |
| for misplacing calls.</p><p> |
| A consequence of this is that there is no need for providing |
| <tt>traceEntry</tt> and <tt>traceExit</tt> as |
| public operations of this class. You can see that they were |
| classified as protected. They are supposed to be internal |
| implementation details of the advice. |
| </p><p> |
| The key piece of this aspect is the abstract pointcut classes that |
| serves as the base for the definition of the pointcuts constructors |
| and methods. Even though <tt>classes</tt> is |
| abstract, and therefore no concrete classes are mentioned, we can |
| put advice on it, as well as on the pointcuts that are based on |
| it. The idea is "we don't know exactly what the pointcut will be, |
| but when we do, here's what we want to do with it." In some ways, |
| abstract pointcuts are similar to abstract methods. Abstract |
| methods don't provide the implementation, but you know that the |
| concrete subclasses will, so you can invoke those methods. |
| </p></div></div></div><div class="sect1"><a name="examples-production"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="examples-production"></a>Production Aspects</h2></div></div><div class="sect2"><a name="a-bean-aspect"></a><div class="titlepage"><div><h3 class="title"><a name="a-bean-aspect"></a>A Bean Aspect</h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/bean</tt>.) |
| </p><p> |
| This example examines an aspect that makes Point objects into |
| Java beans with bound properties. |
| </p><p> |
| Java beans are reusable software components that can be visually |
| manipulated in a builder tool. The requirements for an object to be |
| a bean are few. Beans must define a no-argument constructor and |
| must be either <tt>Serializable</tt> or |
| <tt>Externalizable</tt>. Any properties of the object |
| that are to be treated as bean properties should be indicated by |
| the presence of appropriate <tt>get</tt> and |
| <tt>set</tt> methods whose names are |
| <tt>get</tt><span class="emphasis"><i>property</i></span> and |
| <tt>set </tt><span class="emphasis"><i>property</i></span> where |
| <span class="emphasis"><i>property</i></span> is the name of a field in the bean |
| class. Some bean properties, known as bound properties, fire events |
| whenever their values change so that any registered listeners (such |
| as, other beans) will be informed of those changes. Making a bound |
| property involves keeping a list of registered listeners, and |
| creating and dispatching event objects in methods that change the |
| property values, such as set<span class="emphasis"><i>property</i></span> |
| methods. |
| </p><p> |
| <tt>Point</tt> is a simple class representing points |
| with rectangular coordinates. <tt>Point</tt> does not |
| know anything about being a bean: there are set methods for |
| <tt>x</tt> and <tt>y</tt> but they do not fire |
| events, and the class is not serializable. Bound is an aspect that |
| makes <tt>Point</tt> a serializable class and makes |
| its <tt>get</tt> and <tt>set</tt> methods |
| support the bound property protocol. |
| </p><div class="sect3"><a name="d0e2767"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2767"></a>The <tt>Point</tt> class</h4></div></div><p> |
| The <tt>Point</tt> class is a very simple class with |
| trivial getters and setters, and a simple vector offset method. |
| </p><pre class="programlisting"> |
| class Point { |
| |
| protected int x = 0; |
| protected int y = 0; |
| |
| public int getX() { |
| return x; |
| } |
| |
| public int getY() { |
| return y; |
| } |
| |
| public void setRectangular(int newX, int newY) { |
| setX(newX); |
| setY(newY); |
| } |
| |
| public void setX(int newX) { |
| x = newX; |
| } |
| |
| public void setY(int newY) { |
| y = newY; |
| } |
| |
| public void offset(int deltaX, int deltaY) { |
| setRectangular(x + deltaX, y + deltaY); |
| } |
| |
| public String toString() { |
| return "(" + getX() + ", " + getY() + ")" ; |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e2780"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2780"></a>The <tt>BoundPoint</tt> aspect</h4></div></div><p> |
| The <tt>BoundPoint</tt> aspect is responsible for |
| <tt>Point</tt>'s "beanness". The first thing it does is |
| privately declare that each <tt>Point</tt> has a |
| <tt>support</tt> field that holds reference to an |
| instance of <tt>PropertyChangeSupport</tt>. |
| |
| <pre class="programlisting"> |
| private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); |
| </pre> |
| |
| The property change support object must be constructed with a |
| reference to the bean for which it is providing support, so it is |
| initialized by passing it <tt>this</tt>, an instance of |
| <tt>Point</tt>. Since the <tt>support</tt> |
| field is private declared in the aspect, only the code in the |
| aspect can refer to it. |
| </p><p> |
| The aspect also declares <tt>Point</tt>'s methods for |
| registering and managing listeners for property change events, |
| which delegate the work to the property change support object: |
| |
| <pre class="programlisting"> |
| public void Point.addPropertyChangeListener(PropertyChangeListener listener){ |
| support.addPropertyChangeListener(listener); |
| } |
| public void Point.addPropertyChangeListener(String propertyName, |
| PropertyChangeListener listener){ |
| |
| support.addPropertyChangeListener(propertyName, listener); |
| } |
| public void Point.removePropertyChangeListener(String propertyName, |
| PropertyChangeListener listener) { |
| support.removePropertyChangeListener(propertyName, listener); |
| } |
| public void Point.removePropertyChangeListener(PropertyChangeListener listener) { |
| support.removePropertyChangeListener(listener); |
| } |
| public void Point.hasListeners(String propertyName) { |
| support.hasListeners(propertyName); |
| } |
| </pre> |
| </p><p> |
| The aspect is also responsible for making sure |
| <tt>Point</tt> implements the |
| <tt>Serializable</tt> interface: |
| |
| <pre class="programlisting"> |
| declare parents: Point implements Serializable; |
| </pre> |
| |
| Implementing this interface in Java does not require any methods to |
| be implemented. Serialization for <tt>Point</tt> |
| objects is provided by the default serialization method. |
| </p><p> |
| The <tt>setters</tt> pointcut picks out calls to the |
| <tt>Point</tt>'s <tt>set</tt> methods: any |
| method whose name begins with "<tt>set</tt>" and takes |
| one parameter. The around advice on <tt>setters()</tt> |
| stores the values of the <tt>X</tt> and |
| <tt>Y</tt> properties, calls the original |
| <tt>set</tt> method and then fires the appropriate |
| property change event according to which set method was |
| called. |
| </p><pre class="programlisting"> |
| aspect BoundPoint { |
| private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); |
| |
| public void Point.addPropertyChangeListener(PropertyChangeListener listener){ |
| support.addPropertyChangeListener(listener); |
| } |
| public void Point.addPropertyChangeListener(String propertyName, |
| PropertyChangeListener listener){ |
| |
| support.addPropertyChangeListener(propertyName, listener); |
| } |
| public void Point.removePropertyChangeListener(String propertyName, |
| PropertyChangeListener listener) { |
| support.removePropertyChangeListener(propertyName, listener); |
| } |
| public void Point.removePropertyChangeListener(PropertyChangeListener listener) { |
| support.removePropertyChangeListener(listener); |
| } |
| public void Point.hasListeners(String propertyName) { |
| support.hasListeners(propertyName); |
| } |
| |
| declare parents: Point implements Serializable; |
| |
| pointcut setter(Point p): call(void Point.set*(*)) && target(p); |
| |
| void around(Point p): setter(p) { |
| String propertyName = |
| thisJoinPointStaticPart.getSignature().getName().substring("set".length()); |
| int oldX = p.getX(); |
| int oldY = p.getY(); |
| proceed(p); |
| if (propertyName.equals("X")){ |
| firePropertyChange(p, propertyName, oldX, p.getX()); |
| } else { |
| firePropertyChange(p, propertyName, oldY, p.getY()); |
| } |
| } |
| |
| void firePropertyChange(Point p, |
| String property, |
| double oldval, |
| double newval) { |
| p.support.firePropertyChange(property, |
| new Double(oldval), |
| new Double(newval)); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e2865"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2865"></a>The Test Program</h4></div></div><p> |
| The test program registers itself as a property change listener to |
| a <tt>Point</tt> object that it creates and then performs |
| simple manipulation of that point: calling its set methods and the |
| offset method. Then it serializes the point and writes it to a file |
| and then reads it back. The result of saving and restoring the |
| point is that a new point is created. |
| </p><pre class="programlisting"> |
| class Demo implements PropertyChangeListener { |
| |
| static final String fileName = "test.tmp"; |
| |
| public void propertyChange(PropertyChangeEvent e){ |
| System.out.println("Property " + e.getPropertyName() + " changed from " + |
| e.getOldValue() + " to " + e.getNewValue() ); |
| } |
| |
| public static void main(String[] args){ |
| Point p1 = new Point(); |
| p1.addPropertyChangeListener(new Demo()); |
| System.out.println("p1 =" + p1); |
| p1.setRectangular(5,2); |
| System.out.println("p1 =" + p1); |
| p1.setX( 6 ); |
| p1.setY( 3 ); |
| System.out.println("p1 =" + p1); |
| p1.offset(6,4); |
| System.out.println("p1 =" + p1); |
| save(p1, fileName); |
| Point p2 = (Point) restore(fileName); |
| System.out.println("Had: " + p1); |
| System.out.println("Got: " + p2); |
| } |
| ... |
| } |
| </pre></div><div class="sect3"><a name="d0e2875"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2875"></a>Compiling and Running the Example</h4></div></div><p> |
| To compile and run this example, go to the examples directory and type: |
| </p><pre class="programlisting"> |
| ajc -argfile bean/files.lst |
| java bean.Demo |
| </pre></div></div><div class="sect2"><a name="the-subject-observer-protocol"></a><div class="titlepage"><div><h3 class="title"><a name="the-subject-observer-protocol"></a>The Subject/Observer Protocol</h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/observer</tt>.) |
| </p><p> |
| This demo illustrates how the Subject/Observer design pattern can be |
| coded with aspects. |
| </p><p> |
| The demo consists of the following: A colored label is a |
| renderable object that has a color that cycles through a set of |
| colors, and a number that records the number of cycles it has been |
| through. A button is an action item that records when it is |
| clicked. |
| </p><p> |
| With these two kinds of objects, we can build up a Subject/Observer |
| relationship in which colored labels observe the clicks of buttons; |
| that is, where colored labels are the observers and buttons are the |
| subjects. |
| </p><p> |
| The demo is designed and implemented using the Subject/Observer |
| design pattern. The remainder of this example explains the classes |
| and aspects of this demo, and tells you how to run it. |
| </p><div class="sect3"><a name="d0e2901"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2901"></a>Generic Components</h4></div></div><p> |
| The generic parts of the protocol are the interfaces |
| <tt>Subject</tt> and <tt>Observer</tt>, |
| and the abstract aspect |
| <tt>SubjectObserverProtocol</tt>. The |
| <tt>Subject</tt> interface is simple, containing |
| methods to add, remove, and view <tt>Observer</tt> |
| objects, and a method for getting data about state changes: |
| </p><pre class="programlisting"> |
| interface Subject { |
| void addObserver(Observer obs); |
| void removeObserver(Observer obs); |
| Vector getObservers(); |
| Object getData(); |
| } |
| </pre><p> |
| The <tt>Observer</tt> interface is just as simple, |
| with methods to set and get <tt>Subject</tt> objects, |
| and a method to call when the subject gets updated. |
| </p><pre class="programlisting"> |
| interface Observer { |
| void setSubject(Subject s); |
| Subject getSubject(); |
| void update(); |
| } |
| </pre><p> |
| The <tt>SubjectObserverProtocol</tt> aspect contains |
| within it all of the generic parts of the protocol, namely, how to |
| fire the <tt>Observer</tt> objects' update methods |
| when some state changes in a subject. |
| </p><pre class="programlisting"> |
| abstract aspect SubjectObserverProtocol { |
| |
| abstract pointcut stateChanges(Subject s); |
| |
| after(Subject s): stateChanges(s) { |
| for (int i = 0; i < s.getObservers().size(); i++) { |
| ((Observer)s.getObservers().elementAt(i)).update(); |
| } |
| } |
| |
| private Vector Subject.observers = new Vector(); |
| public void Subject.addObserver(Observer obs) { |
| observers.addElement(obs); |
| obs.setSubject(this); |
| } |
| public void Subject.removeObserver(Observer obs) { |
| observers.removeElement(obs); |
| obs.setSubject(null); |
| } |
| public Vector Subject.getObservers() { return observers; } |
| |
| private Subject Observer.subject = null; |
| public void Observer.setSubject(Subject s) { subject = s; } |
| public Subject Observer.getSubject() { return subject; } |
| |
| } |
| </pre><p> |
| Note that this aspect does three things. It define an abstract |
| pointcut that extending aspects can override. It defines advice |
| that should run after the join points of the pointcut. And it |
| declares an inter-tpye field and two inter-type methods so that |
| each <tt>Observer</tt> can hold onto its <tt>Subject</tt>. |
| </p></div><div class="sect3"><a name="d0e2951"></a><div class="titlepage"><div><h4 class="title"><a name="d0e2951"></a>Application Classes</h4></div></div><p> |
| <tt>Button</tt> objects extend |
| <tt>java.awt.Button</tt>, and all they do is make |
| sure the <tt>void click()</tt> method is called whenever |
| a button is clicked. |
| </p><pre class="programlisting"> |
| class Button extends java.awt.Button { |
| |
| static final Color defaultBackgroundColor = Color.gray; |
| static final Color defaultForegroundColor = Color.black; |
| static final String defaultText = "cycle color"; |
| |
| Button(Display display) { |
| super(); |
| setLabel(defaultText); |
| setBackground(defaultBackgroundColor); |
| setForeground(defaultForegroundColor); |
| addActionListener(new ActionListener() { |
| public void actionPerformed(ActionEvent e) { |
| Button.this.click(); |
| } |
| }); |
| display.addToFrame(this); |
| } |
| |
| public void click() {} |
| |
| } |
| </pre><p> |
| Note that this class knows nothing about being a Subject. |
| </p><p> |
| ColorLabel objects are labels that support the void colorCycle() |
| method. Again, they know nothing about being an observer. |
| </p><pre class="programlisting"> |
| class ColorLabel extends Label { |
| |
| ColorLabel(Display display) { |
| super(); |
| display.addToFrame(this); |
| } |
| |
| final static Color[] colors = {Color.red, Color.blue, |
| Color.green, Color.magenta}; |
| private int colorIndex = 0; |
| private int cycleCount = 0; |
| void colorCycle() { |
| cycleCount++; |
| colorIndex = (colorIndex + 1) % colors.length; |
| setBackground(colors[colorIndex]); |
| setText("" + cycleCount); |
| } |
| } |
| </pre><p> |
| Finally, the <tt>SubjectObserverProtocolImpl</tt> |
| implements the subject/observer protocol, with |
| <tt>Button</tt> objects as subjects and |
| <tt>ColorLabel</tt> objects as observers: |
| </p><pre class="programlisting"> |
| package observer; |
| |
| import java.util.Vector; |
| |
| aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol { |
| |
| declare parents: Button implements Subject; |
| public Object Button.getData() { return this; } |
| |
| declare parents: ColorLabel implements Observer; |
| public void ColorLabel.update() { |
| colorCycle(); |
| } |
| |
| pointcut stateChanges(Subject s): |
| target(s) && |
| call(void Button.click()); |
| |
| }</pre><p> |
| It does this by assuring that <tt>Button</tt> and |
| <tt>ColorLabel</tt> implement the appropriate |
| interfaces, declaring that they implement the methods required by |
| those interfaces, and providing a definition for the abstract |
| <tt>stateChanges</tt> pointcut. Now, every time a |
| <tt>Button</tt> is clicked, all |
| <tt>ColorLabel</tt> objects observing that button |
| will <tt>colorCycle</tt>. |
| </p></div><div class="sect3"><a name="d0e3006"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3006"></a>Compiling and Running</h4></div></div><p> |
| <tt>Demo</tt> is the top class that starts this |
| demo. It instantiates a two buttons and three observers and links |
| them together as subjects and observers. So to run the demo, go to |
| the <tt>examples</tt> directory and type: |
| </p><pre class="programlisting"> |
| ajc -argfile observer/files.lst |
| java observer.Demo |
| </pre></div></div><div class="sect2"><a name="a-simple-telecom-simulation"></a><div class="titlepage"><div><h3 class="title"><a name="a-simple-telecom-simulation"></a>A Simple Telecom Simulation</h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/telecom</tt>.) |
| </p><p> |
| This example illustrates some ways that dependent concerns can be |
| encoded with aspects. It uses an example system comprising a simple |
| model of telephone connections to which timing and billing features |
| are added using aspects, where the billing feature depends upon the |
| timing feature. |
| </p><div class="sect3"><a name="d0e3032"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3032"></a>The Application</h4></div></div><p> |
| The example application is a simple simulation of a telephony |
| system in which customers make, accept, merge and hang-up both |
| local and long distance calls. The application architecture is in |
| three layers. |
| </p><div class="itemizedlist"><ul><li><p><a name="d0e3038"></a> |
| The basic objects provide basic functionality to simulate |
| customers, calls and connections (regular calls have one |
| connection, conference calls have more than one). |
| </p></li><li><p><a name="d0e3041"></a> |
| The timing feature is concerned with timing the connections |
| and keeping the total connection time per customer. Aspects |
| are used to add a timer to each connection and to manage the |
| total time per customer. |
| </p></li><li><p><a name="d0e3044"></a> |
| The billing feature is concerned with charging customers for |
| the calls they make. Aspects are used to calculate a charge |
| per connection and, upon termination of a connection, to add |
| the charge to the appropriate customer's bill. The billing |
| aspect builds upon the timing aspect: it uses a pointcut |
| defined in Timing and it uses the timers that are associated |
| with connections. |
| </p></li></ul></div><p> |
| The simulation of system has three configurations: basic, timing |
| and billing. Programs for the three configurations are in classes |
| <tt>BasicSimulation</tt>, |
| <tt>TimingSimulation</tt> and |
| <tt>BillingSimulation</tt>. These share a common |
| superclass <tt>AbstractSimulation</tt>, which |
| defines the method run with the simulation itself and the method |
| wait used to simulate elapsed time. |
| </p></div><div class="sect3"><a name="d0e3061"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3061"></a>The Basic Objects</h4></div></div><p> |
| The telecom simulation comprises the classes |
| <tt>Customer</tt>, <tt>Call</tt> and |
| the abstract class <tt>Connection</tt> with its two |
| concrete subclasses <tt>Local</tt> and |
| <tt>LongDistance</tt>. Customers have a name and a |
| numeric area code. They also have methods for managing |
| calls. Simple calls are made between one customer (the caller) |
| and another (the receiver), a <tt>Connection</tt> |
| object is used to connect them. Conference calls between more |
| than two customers will involve more than one connection. A |
| customer may be involved in many calls at one time. |
| |
| <span class="inlinemediaobject"><img src="telecom.gif"></span> |
| </p></div><div class="sect3"><a name="d0e3088"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3088"></a>The <tt>Customer</tt> class</h4></div></div><p> |
| <tt>Customer</tt> has methods |
| <tt>call</tt>, <tt>pickup</tt>, |
| <tt>hangup</tt> and <tt>merge</tt> for |
| managing calls. |
| </p><pre class="programlisting"> |
| public class Customer { |
| |
| private String name; |
| private int areacode; |
| private Vector calls = new Vector(); |
| |
| protected void removeCall(Call c){ |
| calls.removeElement(c); |
| } |
| |
| protected void addCall(Call c){ |
| calls.addElement(c); |
| } |
| |
| public Customer(String name, int areacode) { |
| this.name = name; |
| this.areacode = areacode; |
| } |
| |
| public String toString() { |
| return name + "(" + areacode + ")"; |
| } |
| |
| public int getAreacode(){ |
| return areacode; |
| } |
| |
| public boolean localTo(Customer other){ |
| return areacode == other.areacode; |
| } |
| |
| public Call call(Customer receiver) { |
| Call call = new Call(this, receiver); |
| addCall(call); |
| return call; |
| } |
| |
| public void pickup(Call call) { |
| call.pickup(); |
| addCall(call); |
| } |
| |
| public void hangup(Call call) { |
| call.hangup(this); |
| removeCall(call); |
| } |
| |
| public void merge(Call call1, Call call2){ |
| call1.merge(call2); |
| removeCall(call2); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e3113"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3113"></a>The <tt>Call</tt> class</h4></div></div><p> |
| Calls are created with a caller and receiver who are customers. If |
| the caller and receiver have the same area code then the call can |
| be established with a <tt>Local</tt> connection (see |
| below), otherwise a <tt>LongDistance</tt> connection |
| is required. A call comprises a number of connections between |
| customers. Initially there is only the connection between the |
| caller and receiver but additional connections can be added if |
| calls are merged to form conference calls. |
| </p></div><div class="sect3"><a name="d0e3127"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3127"></a>The <tt>Connection</tt> class</h4></div></div><p> |
| The class <tt>Connection</tt> models the physical |
| details of establishing a connection between customers. It does |
| this with a simple state machine (connections are initially |
| <tt>PENDING</tt>, then <tt>COMPLETED</tt> and |
| finally <tt>DROPPED</tt>). Messages are printed to the |
| console so that the state of connections can be |
| observed. Connection is an abstract class with two concrete |
| subclasses: <tt>Local</tt> and |
| <tt>LongDistance</tt>. |
| </p><pre class="programlisting"> |
| abstract class Connection { |
| |
| public static final int PENDING = 0; |
| public static final int COMPLETE = 1; |
| public static final int DROPPED = 2; |
| |
| Customer caller, receiver; |
| private int state = PENDING; |
| |
| Connection(Customer a, Customer b) { |
| this.caller = a; |
| this.receiver = b; |
| } |
| |
| public int getState(){ |
| return state; |
| } |
| |
| public Customer getCaller() { return caller; } |
| |
| public Customer getReceiver() { return receiver; } |
| |
| void complete() { |
| state = COMPLETE; |
| System.out.println("connection completed"); |
| } |
| |
| void drop() { |
| state = DROPPED; |
| System.out.println("connection dropped"); |
| } |
| |
| public boolean connects(Customer c){ |
| return (caller == c || receiver == c); |
| } |
| |
| } |
| </pre></div><div class="sect3"><a name="d0e3155"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3155"></a>The <tt>Local</tt> and <tt>LongDistance</tt> classes</h4></div></div><p> |
| The two kinds of connections supported by our simulation are |
| <tt>Local</tt> and <tt>LongDistance</tt> |
| connections. |
| </p><pre class="programlisting"> |
| class Local extends Connection { |
| Local(Customer a, Customer b) { |
| super(a, b); |
| System.out.println("[new local connection from " + |
| a + " to " + b + "]"); |
| } |
| } |
| </pre><pre class="programlisting"> |
| class LongDistance extends Connection { |
| LongDistance(Customer a, Customer b) { |
| super(a, b); |
| System.out.println("[new long distance connection from " + |
| a + " to " + b + "]"); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e3176"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3176"></a>Compiling and Running the Basic Simulation</h4></div></div><p> |
| The source files for the basic system are listed in the file |
| <tt>basic.lst</tt>. To build and run the basic system, |
| in a shell window, type these commands: |
| </p><pre class="programlisting"> |
| ajc -argfile telecom/basic.lst |
| java telecom.BasicSimulation |
| </pre></div><div class="sect3"><a name="d0e3186"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3186"></a>The Timing aspect</h4></div></div><p> |
| The <tt>Timing</tt> aspect keeps track of total |
| connection time for each <tt>Customer</tt> by |
| starting and stopping a timer associated with each connection. It |
| uses some helper classes: |
| </p><div class="sect4"><a name="d0e3197"></a><div class="titlepage"><div><h5 class="title"><a name="d0e3197"></a>The <tt>Timer</tt> class</h5></div></div><p> |
| A <tt>Timer</tt> object simply records the current |
| time when it is started and stopped, and returns their difference |
| when asked for the elapsed time. The aspect |
| <tt>TimerLog</tt> (below) can be used to cause the |
| start and stop times to be printed to standard output. |
| </p><pre class="programlisting"> |
| class Timer { |
| long startTime, stopTime; |
| |
| public void start() { |
| startTime = System.currentTimeMillis(); |
| stopTime = startTime; |
| } |
| |
| public void stop() { |
| stopTime = System.currentTimeMillis(); |
| } |
| |
| public long getTime() { |
| return stopTime - startTime; |
| } |
| } |
| </pre></div></div><div class="sect3"><a name="d0e3213"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3213"></a>The <tt>TimerLog</tt> aspect</h4></div></div><p> |
| The <tt>TimerLog</tt> aspect can be included in a |
| build to get the timer to announce when it is started and |
| stopped. |
| </p><pre class="programlisting"> |
| public aspect TimerLog { |
| |
| after(Timer t): target(t) && call(* Timer.start()) { |
| System.err.println("Timer started: " + t.startTime); |
| } |
| |
| after(Timer t): target(t) && call(* Timer.stop()) { |
| System.err.println("Timer stopped: " + t.stopTime); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e3226"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3226"></a>The <tt>Timing</tt> aspect</h4></div></div><p> |
| The <tt>Timing</tt> aspect is declares an |
| inter-type field <tt>totalConnectTime</tt> for |
| <tt>Customer</tt> to store the accumulated connection |
| time per <tt>Customer</tt>. It also declares that |
| each <tt>Connection</tt> object has a timer. |
| |
| <pre class="programlisting"> |
| public long Customer.totalConnectTime = 0; |
| private Timer Connection.timer = new Timer(); |
| </pre> |
| |
| Two pieces of after advice ensure that the timer is started when |
| a connection is completed and and stopped when it is dropped. The |
| pointcut <tt>endTiming</tt> is defined so that it can |
| be used by the <tt>Billing</tt> aspect. |
| </p><pre class="programlisting"> |
| public aspect Timing { |
| |
| public long Customer.totalConnectTime = 0; |
| |
| public long getTotalConnectTime(Customer cust) { |
| return cust.totalConnectTime; |
| } |
| private Timer Connection.timer = new Timer(); |
| public Timer getTimer(Connection conn) { return conn.timer; } |
| |
| after (Connection c): target(c) && call(void Connection.complete()) { |
| getTimer(c).start(); |
| } |
| |
| pointcut endTiming(Connection c): target(c) && |
| call(void Connection.drop()); |
| |
| after(Connection c): endTiming(c) { |
| getTimer(c).stop(); |
| c.getCaller().totalConnectTime += getTimer(c).getTime(); |
| c.getReceiver().totalConnectTime += getTimer(c).getTime(); |
| } |
| }</pre></div><div class="sect3"><a name="d0e3260"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3260"></a>The <tt>Billing</tt> aspect</h4></div></div><p> |
| The Billing system adds billing functionality to the telecom |
| application on top of timing. |
| </p><p> |
| The <tt>Billing</tt> aspect declares that each |
| <tt>Connection</tt> has a <tt>payer</tt> |
| inter-type field to indicate who initiated the call and therefore |
| who is responsible to pay for it. It also declares the inter-type |
| method <tt>callRate</tt> of |
| <tt>Connection</tt> so that local and long distance |
| calls can be charged differently. The call charge must be |
| calculated after the timer is stopped; the after advice on pointcut |
| <tt>Timing.endTiming</tt> does this, and |
| <tt>Billing</tt> is declared to be more precedent |
| than <tt>Timing</tt> to make sure that this advice |
| runs after <tt>Timing</tt>'s advice on the same join |
| point. Finally, it declares inter-type methods and fields for |
| <tt>Customer</tt> to handle the |
| <tt>totalCharge</tt>. |
| </p><pre class="programlisting"> |
| public aspect Billing { |
| // precedence required to get advice on endtiming in the right order |
| declare precedence: Billing, Timing; |
| |
| public static final long LOCAL_RATE = 3; |
| public static final long LONG_DISTANCE_RATE = 10; |
| |
| public Customer Connection.payer; |
| public Customer getPayer(Connection conn) { return conn.payer; } |
| |
| after(Customer cust) returning (Connection conn): |
| args(cust, ..) && call(Connection+.new(..)) { |
| conn.payer = cust; |
| } |
| |
| public abstract long Connection.callRate(); |
| |
| public long LongDistance.callRate() { return LONG_DISTANCE_RATE; } |
| public long Local.callRate() { return LOCAL_RATE; } |
| |
| after(Connection conn): Timing.endTiming(conn) { |
| long time = Timing.aspectOf().getTimer(conn).getTime(); |
| long rate = conn.callRate(); |
| long cost = rate * time; |
| getPayer(conn).addCharge(cost); |
| } |
| |
| public long Customer.totalCharge = 0; |
| public long getTotalCharge(Customer cust) { return cust.totalCharge; } |
| |
| public void Customer.addCharge(long charge){ |
| totalCharge += charge; |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e3305"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3305"></a>Accessing the inter-type state</h4></div></div><p> |
| Both the aspects <tt>Timing</tt> and |
| <tt>Billing</tt> contain the definition of operations |
| that the rest of the system may want to access. For example, when |
| running the simulation with one or both aspects, we want to find |
| out how much time each customer spent on the telephone and how big |
| their bill is. That information is also stored in the classes, but |
| they are accessed through static methods of the aspects, since the |
| state they refer to is private to the aspect. |
| </p><p> |
| Take a look at the file |
| <tt>TimingSimulation.java</tt>. The most important |
| method of this class is the method |
| <tt>report(Customer)</tt>, which is used in the method |
| run of the superclass |
| <tt>AbstractSimulation</tt>. This method is intended |
| to print out the status of the customer, with respect to the |
| <tt>Timing</tt> feature. |
| </p><pre class="programlisting"> |
| protected void report(Customer c){ |
| Timing t = Timing.aspectOf(); |
| System.out.println(c + " spent " + t.getTotalConnectTime(c)); |
| } |
| </pre></div><div class="sect3"><a name="d0e3332"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3332"></a>Compiling and Running</h4></div></div><p> |
| The files timing.lst and billing.lst contain file lists for the |
| timing and billing configurations. To build and run the application |
| with only the timing feature, go to the directory examples and |
| type: |
| </p><pre class="programlisting"> |
| ajc -argfile telecom/timing.lst |
| java telecom.TimingSimulation |
| </pre><p> |
| To build and run the application with the timing and billing |
| features, go to the directory examples and type: |
| </p><pre class="programlisting"> |
| ajc -argfile telecom/billing.lst |
| java telecom.BillingSimulation |
| </pre></div><div class="sect3"><a name="d0e3343"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3343"></a>Discussion</h4></div></div><p> |
| There are some explicit dependencies between the aspects Billing |
| and Timing: |
| |
| <div class="itemizedlist"><ul><li><p><a name="d0e3349"></a> |
| Billing is declared more precedent than Timing so that Billing's |
| after advice runs after that of Timing when they are on the |
| same join point. |
| </p></li><li><p><a name="d0e3352"></a> |
| Billing uses the pointcut Timing.endTiming. |
| </p></li><li><p><a name="d0e3355"></a> |
| Billing needs access to the timer associated with a connection. |
| </p></li></ul></div> |
| </p></div></div></div><div class="sect1"><a name="examples-reusable"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="examples-reusable"></a>Reusable Aspects</h2></div></div><div class="sect2"><a name="tracing-using-aspects-revisited"></a><div class="titlepage"><div><h3 class="title"><a name="tracing-using-aspects-revisited"></a>Tracing using Aspects, Revisited</h3></div></div><p> |
| (The code for this example is in |
| <tt><i><tt>InstallDir</tt></i>/examples/tracing</tt>.) |
| </p><div class="sect3"><a name="d0e3374"></a><div class="titlepage"><div><h4 class="title"><a name="d0e3374"></a>Tracing—Version 3</h4></div></div><p> |
| One advantage of not exposing the methods traceEntry and |
| traceExit as public operations is that we can easily change their |
| interface without any dramatic consequences in the rest of the |
| code. |
| </p><p> |
| Consider, again, the program without AspectJ. Suppose, for |
| example, that at some point later the requirements for tracing |
| change, stating that the trace messages should always include the |
| string representation of the object whose methods are being |
| traced. This can be achieved in at least two ways. One way is |
| keep the interface of the methods <tt>traceEntry</tt> |
| and <tt>traceExit</tt> as it was before, |
| </p><pre class="programlisting"> |
| public static void traceEntry(String str); |
| public static void traceExit(String str); |
| </pre><p> |
| In this case, the caller is responsible for ensuring that the |
| string representation of the object is part of the string given |
| as argument. So, calls must look like: |
| </p><pre class="programlisting"> |
| Trace.traceEntry("Square.distance in " + toString()); |
| </pre><p> |
| Another way is to enforce the requirement with a second argument |
| in the trace operations, e.g. |
| </p><pre class="programlisting"> |
| public static void traceEntry(String str, Object obj); |
| public static void traceExit(String str, Object obj); |
| </pre><p> |
| In this case, the caller is still responsible for sending the |
| right object, but at least there is some guarantees that some |
| object will be passed. The calls will look like: |
| </p><pre class="programlisting"> |
| Trace.traceEntry("Square.distance", this); |
| </pre><p> |
| In either case, this change to the requirements of tracing will |
| have dramatic consequences in the rest of the code -- every call |
| to the trace operations traceEntry and traceExit must be changed! |
| </p><p> |
| Here's another advantage of doing tracing with an aspect. We've |
| already seen that in version 2 <tt>traceEntry</tt> and |
| <tt>traceExit</tt> are not publicly exposed. So |
| changing their interfaces, or the way they are used, has only a |
| small effect inside the <tt>Trace</tt> |
| class. Here's a partial view at the implementation of |
| <tt>Trace</tt>, version 3. The differences with |
| respect to version 2 are stressed in the comments: |
| </p><pre class="programlisting"> |
| abstract aspect Trace { |
| |
| public static int TRACELEVEL = 0; |
| protected static PrintStream stream = null; |
| protected static int callDepth = 0; |
| |
| public static void initStream(PrintStream s) { |
| stream = s; |
| } |
| |
| protected static void traceEntry(String str, Object o) { |
| if (TRACELEVEL == 0) return; |
| if (TRACELEVEL == 2) callDepth++; |
| printEntering(str + ": " + o.toString()); |
| } |
| |
| protected static void traceExit(String str, Object o) { |
| if (TRACELEVEL == 0) return; |
| printExiting(str + ": " + o.toString()); |
| if (TRACELEVEL == 2) callDepth--; |
| } |
| |
| private static void printEntering(String str) { |
| printIndent(); |
| stream.println("Entering " + str); |
| } |
| |
| private static void printExiting(String str) { |
| printIndent(); |
| stream.println("Exiting " + str); |
| } |
| |
| private static void printIndent() { |
| for (int i = 0; i < callDepth; i++) |
| stream.print(" "); |
| } |
| |
| abstract pointcut myClass(Object obj); |
| |
| pointcut myConstructor(Object obj): myClass(obj) && execution(new(..)); |
| pointcut myMethod(Object obj): myClass(obj) && |
| execution(* *(..)) && !execution(String toString()); |
| |
| before(Object obj): myConstructor(obj) { |
| traceEntry("" + thisJoinPointStaticPart.getSignature(), obj); |
| } |
| after(Object obj): myConstructor(obj) { |
| traceExit("" + thisJoinPointStaticPart.getSignature(), obj); |
| } |
| |
| before(Object obj): myMethod(obj) { |
| traceEntry("" + thisJoinPointStaticPart.getSignature(), obj); |
| } |
| after(Object obj): myMethod(obj) { |
| traceExit("" + thisJoinPointStaticPart.getSignature(), obj); |
| } |
| } |
| </pre><p> |
| As you can see, we decided to apply the first design by preserving |
| the interface of the methods <tt>traceEntry</tt> and |
| <tt>traceExit</tt>. But it doesn't matter—we could |
| as easily have applied the second design (the code in the directory |
| <tt>examples/tracing/version3</tt> has the second |
| design). The point is that the effects of this change in the |
| tracing requirements are limited to the |
| <tt>Trace</tt> aspect class. |
| </p><p> |
| One implementation change worth noticing is the specification of |
| the pointcuts. They now expose the object. To maintain full |
| consistency with the behavior of version 2, we should have included |
| tracing for static methods, by defining another pointcut for static |
| methods and advising it. We leave that as an exercise. |
| </p><p> |
| Moreover, we had to exclude the execution join point of the method |
| <tt>toString</tt> from the <tt>methods</tt> |
| pointcut. The problem here is that <tt>toString</tt> is |
| being called from inside the advice. Therefore if we trace it, we |
| will end up in an infinite recursion of calls. This is a subtle |
| point, and one that you must be aware when writing advice. If the |
| advice calls back to the objects, there is always the possibility |
| of recursion. Keep that in mind! |
| </p><p> |
| In fact, esimply excluding the execution join point may not be |
| enough, if there are calls to other traced methods within it -- in |
| which case, the restriction should be |
| </p><pre class="programlisting"> |
| && !cflow(execution(String toString())) |
| </pre><p> |
| excluding both the execution of toString methods and all join |
| points under that execution. |
| </p><p> |
| In summary, to implement the change in the tracing requirements we |
| had to make a couple of changes in the implementation of the |
| <tt>Trace</tt> aspect class, including changing the |
| specification of the pointcuts. That's only natural. But the |
| implementation changes were limited to this aspect. Without |
| aspects, we would have to change the implementation of every |
| application class. |
| </p><p> |
| Finally, to run this version of tracing, go to the directory |
| <tt>examples</tt> and type: |
| </p><pre class="programlisting"> |
| ajc -argfile tracing/tracev3.lst |
| </pre><p> |
| The file tracev3.lst lists the application classes as well as this |
| version of the files <tt>Trace.java</tt> and |
| <tt>TraceMyClasses.java</tt>. To run the program, type |
| </p><pre class="programlisting"> |
| java tracing.version3.TraceMyClasses |
| </pre><p>The output should be:</p><pre class="programlisting"> |
| --> tracing.TwoDShape(double, double) |
| <-- tracing.TwoDShape(double, double) |
| --> tracing.Circle(double, double, double) |
| <-- tracing.Circle(double, double, double) |
| --> tracing.TwoDShape(double, double) |
| <-- tracing.TwoDShape(double, double) |
| --> tracing.Circle(double, double, double) |
| <-- tracing.Circle(double, double, double) |
| --> tracing.Circle(double) |
| <-- tracing.Circle(double) |
| --> tracing.TwoDShape(double, double) |
| <-- tracing.TwoDShape(double, double) |
| --> tracing.Square(double, double, double) |
| <-- tracing.Square(double, double, double) |
| --> tracing.Square(double, double) |
| <-- tracing.Square(double, double) |
| --> double tracing.Circle.perimeter() |
| <-- double tracing.Circle.perimeter() |
| c1.perimeter() = 12.566370614359172 |
| --> double tracing.Circle.area() |
| <-- double tracing.Circle.area() |
| c1.area() = 12.566370614359172 |
| --> double tracing.Square.perimeter() |
| <-- double tracing.Square.perimeter() |
| s1.perimeter() = 4.0 |
| --> double tracing.Square.area() |
| <-- double tracing.Square.area() |
| s1.area() = 1.0 |
| --> double tracing.TwoDShape.distance(TwoDShape) |
| --> double tracing.TwoDShape.getX() |
| <-- double tracing.TwoDShape.getX() |
| --> double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.distance(TwoDShape) |
| c2.distance(c1) = 4.242640687119285 |
| --> double tracing.TwoDShape.distance(TwoDShape) |
| --> double tracing.TwoDShape.getX() |
| <-- double tracing.TwoDShape.getX() |
| --> double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.getY() |
| <-- double tracing.TwoDShape.distance(TwoDShape) |
| s1.distance(c1) = 2.23606797749979 |
| --> String tracing.Square.toString() |
| --> String tracing.TwoDShape.toString() |
| <-- String tracing.TwoDShape.toString() |
| <-- String tracing.Square.toString() |
| s1.toString(): Square side = 1.0 @ (1.0, 2.0) |
| </pre></div></div></div></div><div class="chapter"><div class="titlepage"><div><h2 class="title"><a name="idioms"></a>Chapter 4. Idioms</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#idioms-intro">Introduction</a></dt></dl></div><div class="sect1"><a name="idioms-intro"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="idioms-intro"></a>Introduction</h2></div></div><p> |
| This chapter consists of very short snippets of AspectJ code, |
| typically pointcuts, that are particularly evocative or useful. |
| This section is a work in progress. |
| </p><p> |
| Here's an example of how to enfore a rule that code in the |
| java.sql package can only be used from one particular package in |
| your system. This doesn't require any access to code in the |
| java.sql package. |
| </p><pre class="programlisting"> |
| /* Any call to methods or constructors in java.sql */ |
| pointcut restrictedCall(): |
| call(* java.sql.*.*(..)) || call(java.sql.*.new(..)); |
| |
| /* Any code in my system not in the sqlAccess package */ |
| pointcut illegalSource(): |
| within(com.foo..*) && !within(com.foo.sqlAccess.*); |
| |
| declare error: restrictedCall() && illegalSource(): |
| "java.sql package can only be accessed from com.foo.sqlAccess"; |
| </pre><p>Any call to an instance of a subtype of AbstractFacade whose class is |
| not exactly equal to AbstractFacade:</p><pre class="programlisting"> |
| pointcut nonAbstract(AbstractFacade af): |
| call(* *(..)) |
| && target(af) |
| && !if(af.getClass() == AbstractFacade.class); |
| </pre><p> If AbstractFacade is an abstract class or an interface, then every |
| instance must be of a subtype and you can replace this with: </p><pre class="programlisting"> |
| pointcut nonAbstract(AbstractFacade af): |
| call(* *(..)) |
| && target(af); |
| </pre><p> Any call to a method which is defined by a subtype of |
| AbstractFacade, but which isn't defined by the type AbstractFacade itself: |
| </p><pre class="programlisting"> |
| pointcut callToUndefinedMethod(): |
| call(* AbstractFacade+.*(..)) |
| && !call(* AbstractFacade.*(..)); |
| </pre><p> The execution of a method that is defined in the source code for a |
| type that is a subtype of AbstractFacade but not in AbstractFacade itself: |
| </p><pre class="programlisting"> |
| pointcut executionOfUndefinedMethod(): |
| execution(* *(..)) |
| && within(AbstractFacade+) |
| && !within(AbstractFacade) |
| </pre></div></div><div class="chapter"><div class="titlepage"><div><h2 class="title"><a name="pitfalls"></a>Chapter 5. Pitfalls</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#pitfalls-intro">Introduction</a></dt><dt><a href="#pitfalls-infiniteLoops">Infinite loops</a></dt></dl></div><div class="sect1"><a name="pitfalls-intro"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="pitfalls-intro"></a>Introduction</h2></div></div><p> |
| This chapter consists of a few AspectJ programs that may lead to |
| surprising behavior and how to understand them. |
| </p></div><div class="sect1"><a name="pitfalls-infiniteLoops"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="pitfalls-infiniteLoops"></a>Infinite loops</h2></div></div><p> |
| Here is a Java program with peculiar behavior |
| </p><pre class="programlisting"> |
| public class Main { |
| public static void main(String[] args) { |
| foo(); |
| System.out.println("done with call to foo"); |
| } |
| |
| static void foo() { |
| try { |
| foo(); |
| } finally { |
| foo(); |
| } |
| } |
| } |
| </pre><p> |
| This program will never reach the println call, but when it aborts |
| may have no stack trace. |
| </p><p> |
| This silence is caused by multiple StackOverflowExceptions. First |
| the infinite loop in the body of the method generates one, which the |
| finally clause tries to handle. But this finally clause also |
| generates an infinite loop which the current JVMs can't handle |
| gracefully leading to the completely silent abort. |
| </p><p> |
| The following short aspect will also generate this behavior: |
| </p><pre class="programlisting"> |
| aspect A { |
| before(): call(* *(..)) { System.out.println("before"); } |
| after(): call(* *(..)) { System.out.println("after"); } |
| } |
| </pre><p> |
| Why? Because the call to println is also a call matched by the |
| pointcut <tt>call (* *(..))</tt>. We get no output because |
| we used simple after() advice. If the aspect were changed to |
| </p><pre class="programlisting"> |
| aspect A { |
| before(): call(* *(..)) { System.out.println("before"); } |
| after() returning: call(* *(..)) { System.out.println("after"); } |
| } |
| </pre><p> |
| Then at least a StackOverflowException with a stack trace would be |
| seen. In both cases, though, the overall problem is advice applying |
| within its own body. |
| </p><p> |
| There's a simple idiom to use if you ever have a worry that your |
| advice might apply in this way. Just restrict the advice from occurring in |
| join points caused within the aspect. So: |
| </p><pre class="programlisting"> |
| aspect A { |
| before(): call(* *(..)) && !within(A) { System.out.println("before"); } |
| after() returning: call(* *(..)) && !within(A) { System.out.println("after"); } |
| } |
| </pre><p> |
| Other solutions might be to more closely restrict the pointcut in |
| other ways, for example: |
| </p><pre class="programlisting"> |
| aspect A { |
| before(): call(* MyObject.*(..)) { System.out.println("before"); } |
| after() returning: call(* MyObject.*(..)) { System.out.println("after"); } |
| } |
| </pre><p> |
| The moral of the story is that unrestricted generic pointcuts can |
| pick out more join points than intended. |
| </p></div></div><div class="appendix"><div class="titlepage"><div><h2 class="title"><a name="quick"></a>Appendix A. AspectJ Quick Reference</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#quick-pointcuts">Pointcuts</a></dt><dt><a href="#quick-typePatterns">Type Patterns</a></dt><dt><a href="#quick-advice">Advice</a></dt><dt><a href="#quick-interType">Inter-type member declarations</a></dt><dt><a href="#quick-other">Other declarations</a></dt><dt><a href="#quick-aspectAssociations">Aspects</a></dt></dl></div><div class="sect1"><a name="quick-pointcuts"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="quick-pointcuts"></a>Pointcuts</h2></div></div><div class="informaltable" id="d0e3554"><a name="d0e3554"></a><table border="0"><colgroup><col align="left"><col align="left"></colgroup><tbody valign="top"><tr><td colspan="2"><span class="bold"><b>Methods and Constructors</b></span></td></tr><tr><td><tt>call(<i><tt>Signature</tt></i>)</tt></td><td> |
| every call to any method or constructor matching |
| <i><tt>Signature</tt></i> at the call site |
| </td></tr><tr><td><tt>execution(<i><tt>Signature</tt></i>)</tt></td><td> |
| every execution of any method or constructor matching |
| <i><tt>Signature</tt></i></td></tr><tr><td colspan="2"><span class="bold"><b>Fields</b></span></td></tr><tr><td><tt>get(<i><tt>Signature</tt></i>)</tt></td><td> |
| every reference to any field matching <i><tt>Signature</tt></i></td></tr><tr><td><tt>set(<i><tt>Signature</tt></i>)</tt></td><td> |
| every assignment to any field matching |
| <i><tt>Signature</tt></i>. The assigned value can |
| be exposed with an <tt>args</tt> pointcut |
| </td></tr><tr><td colspan="2"><span class="bold"><b>Exception Handlers</b></span></td></tr><tr><td><tt>handler(<i><tt>TypePattern</tt></i>)</tt></td><td> |
| every exception handler for any <tt>Throwable</tt> |
| type in <i><tt>TypePattern</tt></i>. The exception |
| value can be exposed with an <tt>args</tt> pointcut |
| </td></tr><tr><td colspan="2"><span class="bold"><b>Advice</b></span></td></tr><tr><td><tt>adviceexecution()</tt></td><td> |
| every execution of any piece of advice |
| </td></tr><tr><td colspan="2"><span class="bold"><b>Initialization</b></span></td></tr><tr><td><tt>staticinitialization(<i><tt>TypePattern</tt></i>)</tt></td><td> |
| every execution of a static initializer for any type in |
| <i><tt>TypePattern</tt></i></td></tr><tr><td><tt>initialization(<i><tt>Signature</tt></i>)</tt></td><td> |
| every initialization of an object when the first constructor |
| called in the type matches |
| <i><tt>Signature</tt></i>, encompassing the return |
| from the super constructor call to the return of the |
| first-called constructor |
| </td></tr><tr><td><tt>preinitialization(<i><tt>Signature</tt></i>)</tt></td><td> |
| every pre-initialization of an object when the first |
| constructor called in the type matches |
| <i><tt>Signature</tt></i>, encompassing the entry |
| of the first-called constructor to the call to the super |
| constructor |
| </td></tr><tr><td colspan="2"><span class="bold"><b>Lexical</b></span></td></tr><tr><td><tt>within(<i><tt>TypePattern</tt></i>)</tt></td><td> |
| every join point from code defined in a type in |
| <i><tt>TypePattern</tt></i></td></tr><tr><td><tt>withincode(<i><tt>Signature</tt></i>)</tt></td><td> |
| every join point from code defined in a method or constructor |
| matching <i><tt>Signature</tt></i></td></tr></tbody></table><table border="0"><colgroup><col align="left"><col align="left"></colgroup><tbody valign="top"><tr><td colspan="2"><span class="bold"><b>Instanceof checks and context exposure</b></span></td></tr><tr><td><tt>this(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>)</tt></td><td> |
| every join point when the currently executing object is an |
| instance of <i><tt>Type</tt></i> or |
| <i><tt>Id</tt></i>'s type |
| </td></tr><tr><td><tt>target(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>)</tt></td><td> |
| every join point when the target executing object is an |
| instance of <i><tt>Type</tt></i> or |
| <i><tt>Id</tt></i>'s type |
| </td></tr><tr><td><tt>args(<i><tt>Type</tt></i> or |
| <i><tt>Id</tt></i>, ...)</tt></td><td> |
| every join point when the arguments are instances of |
| <i><tt>Type</tt></i>s or the types of the |
| <i><tt>Id</tt></i>s |
| </td></tr><tr><td colspan="2"><span class="bold"><b>Control Flow</b></span></td></tr><tr><td><tt>cflow(<i><tt>Pointcut</tt></i>)</tt></td><td> |
| every join point in the control flow of each join point |
| <i><tt>P</tt></i> picked out by |
| <i><tt>Pointcut</tt></i>, including |
| <i><tt>P</tt></i> itself |
| </td></tr><tr><td><tt>cflowbelow(<i><tt>Pointcut</tt></i>)</tt></td><td> |
| every join point below the control flow of each join point |
| <i><tt>P</tt></i> picked out by |
| <i><tt>Pointcut</tt></i>; does not include |
| <i><tt>P</tt></i> itself |
| </td></tr><tr><td colspan="2"><span class="bold"><b>Conditional</b></span></td></tr><tr><td><tt>if(<i><tt>Expression</tt></i>)</tt></td><td> |
| every join point when the boolean |
| <i><tt>Expression</tt></i> is |
| <tt>true</tt></td></tr></tbody></table><table border="0"><colgroup><col align="left"><col align="left"></colgroup><tbody valign="top"><tr><td colspan="2"><span class="bold"><b>Combination</b></span></td></tr><tr><td><tt>! <i><tt>Pointcut</tt></i></tt></td><td> |
| every join point not picked out by |
| <i><tt>Pointcut</tt></i></td></tr><tr><td><tt><i><tt>Pointcut0</tt></i> && <i><tt>Pointcut1</tt></i></tt></td><td> |
| each join point picked out by both |
| <i><tt>Pointcut0</tt></i> and |
| <i><tt>Pointcut1</tt></i></td></tr><tr><td><tt><i><tt>Pointcut0</tt></i> || <i><tt>Pointcut1</tt></i></tt></td><td> |
| each join point picked out by either |
| <i><tt>Pointcut0</tt></i> or |
| <i><tt>Pointcut1</tt></i></td></tr><tr><td><tt>( <i><tt>Pointcut</tt></i> )</tt></td><td> |
| each join point picked out by |
| <i><tt>Pointcut</tt></i></td></tr></tbody></table></div></div><div class="sect1"><a name="quick-typePatterns"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="quick-typePatterns"></a>Type Patterns</h2></div></div><p> |
| A type pattern is one of |
| </p><div class="informaltable" id="d0e3905"><a name="d0e3905"></a><table border="0"><colgroup><col><col></colgroup><tbody valign="top"><tr><td><i><tt>TypeNamePattern</tt></i></td><td>all types in <i><tt>TypeNamePattern</tt></i></td></tr><tr><td><i><tt>SubtypePattern</tt></i></td><td>all types in <i><tt>SubtypePattern</tt></i>, a |
| pattern with a +. </td></tr><tr><td><i><tt>ArrayTypePattern</tt></i></td><td>all types in <i><tt>ArrayTypePattern</tt></i>, |
| a pattern with one or more []s. </td></tr><tr><td><tt>!<i><tt>TypePattern</tt></i></tt></td><td>all types not in <i><tt>TypePattern</tt></i></td></tr><tr><td><tt><i><tt>TypePattern0</tt></i> |
| && <i><tt>TypePattern1</tt></i></tt></td><td>all types in both |
| <i><tt>TypePattern0</tt></i> and <i><tt>TypePattern1</tt></i></td></tr><tr><td><tt><i><tt>TypePattern0</tt></i> || <i><tt>TypePattern1</tt></i></tt></td><td>all types in either |
| <i><tt>TypePattern0</tt></i> or <i><tt>TypePattern1</tt></i></td></tr><tr><td><tt>( <i><tt>TypePattern</tt></i> )</tt></td><td>all types in <i><tt>TypePattern</tt></i></td></tr></tbody></table></div><p> |
| where <i><tt>TypeNamePattern</tt></i> can either be a |
| plain type name, the wildcard <tt>*</tt> (indicating all |
| types), or an identifier with embedded <tt>*</tt> and |
| <tt>..</tt> wildcards. |
| </p><p> |
| An embedded <tt>*</tt> in an identifier matches any |
| sequence of characters, but does not match the package (or |
| inner-type) separator ".". |
| </p><p> |
| An embedded <tt>..</tt> in an identifier matches any |
| sequence of characters that starts and ends with the package (or |
| inner-type) separator ".". |
| </p></div><div class="sect1"><a name="quick-advice"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="quick-advice"></a>Advice</h2></div></div><p> |
| Each piece of advice is of the form |
| |
| <blockquote class="blockquote"><tt>[ strictfp ] <i><tt>AdviceSpec</tt></i> |
| [ throws <i><tt>TypeList</tt></i> ] : |
| <i><tt>Pointcut</tt></i> { |
| <i><tt>Body</tt></i> } </tt></blockquote> |
| |
| where <i><tt>AdviceSpec</tt></i> is one of |
| </p><div class="variablelist"><dl><dt><a name="d0e4035"></a><span class="term"> |
| <tt>before( <i><tt>Formals</tt></i> ) </tt> |
| </span></dt><dd> |
| runs before each join point |
| </dd><dt><a name="d0e4046"></a><span class="term"> |
| <tt>after( <i><tt>Formals</tt></i> ) returning |
| [ ( <i><tt>Formal</tt></i> ) ] </tt> |
| </span></dt><dd> |
| runs after each join point that returns normally. The |
| optional formal gives access to the returned value |
| </dd><dt><a name="d0e4060"></a><span class="term"> |
| <tt>after( <i><tt>Formals</tt></i> ) throwing [ |
| ( <i><tt>Formal</tt></i> ) ] </tt> |
| </span></dt><dd> |
| runs after each join point that throws a |
| <tt>Throwable</tt>. If the optional formal is |
| present, runs only after each join point that throws a |
| <tt>Throwable</tt> of the type of |
| <i><tt>Formal</tt></i>, and |
| <i><tt>Formal</tt></i> gives access to the |
| <tt>Throwable</tt> exception value |
| </dd><dt><a name="d0e4089"></a><span class="term"> |
| <tt>after( <i><tt>Formals</tt></i> ) </tt> |
| </span></dt><dd> |
| runs after each join point regardless of whether it returns |
| normally or throws a <tt>Throwable</tt></dd><dt><a name="d0e4102"></a><span class="term"> |
| <tt><i><tt>Type</tt></i> |
| around( <i><tt>Formals</tt></i> ) </tt> |
| </span></dt><dd> |
| runs in place of each join point. The join point can be |
| executed by calling <tt>proceed</tt>, which takes |
| the same number and types of arguments as the around advice. |
| </dd></dl></div><p> |
| Three special variables are available inside of advice bodies: |
| </p><div class="variablelist"><dl><dt><a name="d0e4121"></a><span class="term"> |
| <tt>thisJoinPoint</tt> |
| </span></dt><dd> |
| an object of type <a href="../api/org/aspectj/lang/JoinPoint.html" target="_top"><tt>org.aspectj.lang.JoinPoint</tt></a> |
| representing the join point at which the advice is executing. |
| </dd><dt><a name="d0e4133"></a><span class="term"> |
| <tt>thisJoinPointStaticPart</tt> |
| </span></dt><dd> |
| equivalent to <tt>thisJoinPoint.getStaticPart()</tt>, |
| but may use fewer runtime resources. |
| </dd><dt><a name="d0e4144"></a><span class="term"> |
| <tt>thisEnclosingJoinPointStaticPart</tt> |
| </span></dt><dd> |
| the static part of the dynamically enclosing join point. |
| </dd></dl></div></div><div class="sect1"><a name="quick-interType"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="quick-interType"></a>Inter-type member declarations</h2></div></div><p> |
| Each inter-type member is one of |
| </p><div class="variablelist"><dl><dt><a name="d0e4159"></a><span class="term"> |
| <tt> |
| <i><tt>Modifiers ReturnType OnType . Id</tt></i> |
| ( <i><tt>Formals</tt></i> ) |
| [ throws <i><tt>TypeList</tt></i> ] |
| { <i><tt>Body</tt></i> } |
| </tt> |
| </span></dt><dd> |
| a method on <i><tt>OnType</tt></i>. |
| </dd><dt><a name="d0e4182"></a><span class="term"> |
| <tt> |
| abstract <i><tt>Modifiers ReturnType OnType . Id</tt></i> |
| ( <i><tt>Formals</tt></i> ) |
| [ throws <i><tt>TypeList</tt></i> ] ; |
| </tt> |
| </span></dt><dd> |
| an abstract method on <i><tt>OnType</tt></i>. |
| </dd><dt><a name="d0e4202"></a><span class="term"> |
| <tt> |
| <i><tt>Modifiers OnType . </tt></i> new |
| ( <i><tt>Formals</tt></i> ) |
| [ throws <i><tt>TypeList</tt></i> ] |
| { <i><tt>Body</tt></i> } |
| </tt> |
| </span></dt><dd> |
| a constructor on <i><tt>OnType</tt></i>. |
| </dd><dt><a name="d0e4225"></a><span class="term"> |
| <tt> |
| <i><tt>Modifiers Type OnType . Id </tt></i> |
| [ = <i><tt>Expression</tt></i> ] ; |
| </tt> |
| </span></dt><dd> |
| a field on <i><tt>OnType</tt></i>. |
| </dd></dl></div></div><div class="sect1"><a name="quick-other"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="quick-other"></a>Other declarations</h2></div></div><div class="variablelist"><dl><dt><a name="d0e4247"></a><span class="term"> |
| <tt> |
| declare parents : |
| <i><tt>TypePattern</tt></i> extends |
| <i><tt>Type</tt></i> ; |
| </tt> |
| </span></dt><dd> |
| the types in <i><tt>TypePattern</tt></i> extend |
| <i><tt>Type</tt></i>. |
| </dd><dt><a name="d0e4267"></a><span class="term"> |
| <tt> |
| declare parents : <i><tt>TypePattern</tt></i> |
| implements <i><tt>TypeList</tt></i> ; |
| </tt> |
| </span></dt><dd> |
| the types in <i><tt>TypePattern</tt></i> |
| implement the types in <i><tt>TypeList</tt></i>. |
| </dd><dt><a name="d0e4287"></a><span class="term"> |
| <tt> |
| declare warning : <i><tt>Pointcut</tt></i> : |
| <i><tt>String</tt></i> ; |
| </tt> |
| </span></dt><dd> |
| if any of the join points in <i><tt>Pointcut</tt></i> |
| possibly exist in the program, the compiler emits the warning |
| <i><tt>String</tt></i>. |
| </dd><dt><a name="d0e4307"></a><span class="term"> |
| <tt> |
| declare error : <i><tt>Pointcut</tt></i> : |
| <i><tt>String</tt></i> ; |
| </tt> |
| </span></dt><dd> |
| if any of the join points in <i><tt>Pointcut</tt></i> |
| could possibly exist in the program, the compiler emits the |
| error <i><tt>String</tt></i>. |
| </dd><dt><a name="d0e4327"></a><span class="term"> |
| <tt> |
| declare soft : |
| <i><tt>Type</tt></i> : |
| <i><tt>Pointcut</tt></i> ; |
| </tt> |
| </span></dt><dd> |
| any <i><tt>Type</tt></i> exception |
| that gets thrown at any join point picked out by |
| <i><tt>Pointcut</tt></i> is wrapped in <a href="../api/org/aspectj/lang/SoftException.html" target="_top"><tt>org.aspectj.lang.SoftException</tt></a>. |
| </dd><dt><a name="d0e4351"></a><span class="term"> |
| <tt> |
| declare precedence : |
| <i><tt>TypePatternList</tt></i> ; |
| </tt> |
| </span></dt><dd> |
| at any join point where multiple pieces of advice |
| apply, the advice precedence at that join point is in |
| <i><tt>TypePatternList</tt></i> order. |
| </dd></dl></div></div><div class="sect1"><a name="quick-aspectAssociations"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="quick-aspectAssociations"></a>Aspects</h2></div></div><p> |
| Each aspect is of the form |
| |
| <blockquote class="blockquote"><tt> |
| [ privileged ] <i><tt>Modifiers</tt></i> |
| aspect <i><tt>Id</tt></i> |
| [ extends <i><tt>Type</tt></i> ] |
| [ implements <i><tt>TypeList</tt></i> ] |
| [ <i><tt>PerClause</tt></i> ] |
| { <i><tt>Body</tt></i> } |
| </tt></blockquote> |
| where <i><tt>PerClause</tt></i> defines how the aspect is |
| instantiated and associated (<tt>issingleton()</tt> by |
| default): |
| </p><div class="informaltable" id="d0e4399"><a name="d0e4399"></a><table border="0"><colgroup><col><col><col></colgroup><thead><tr><th align="left">PerClause</th><th align="left">Description</th><th align="left">Accessor</th></tr></thead><tbody valign="top"><tr><td> |
| [ <tt>issingleton()</tt> ] |
| </td><td> |
| One instance of the aspect is made. This is |
| the default. |
| </td><td><tt>aspectOf()</tt> at all join points |
| </td></tr><tr><td><tt>perthis(<i><tt>Pointcut</tt></i>)</tt></td><td> |
| An instance is associated with each object that is the |
| currently executing object at any join point in |
| <i><tt>Pointcut</tt></i>. |
| </td><td><tt>aspectOf(Object)</tt> at all join points |
| </td></tr><tr><td><tt>pertarget(<i><tt>Pointcut</tt></i>)</tt></td><td> |
| An instance is associated with each object that is the |
| target object at any join point in |
| <i><tt>Pointcut</tt></i>. |
| </td><td><tt>aspectOf(Object)</tt> at all join points |
| </td></tr><tr><td><tt>percflow(<i><tt>Pointcut</tt></i>)</tt></td><td> |
| The aspect is defined for each entrance to the control flow of |
| the join points defined by <i><tt>Pointcut</tt></i>. </td><td><tt>aspectOf()</tt> at join points in |
| <tt>cflow(<i><tt>Pointcut</tt></i>)</tt></td></tr><tr><td><tt>percflowbelow(<i><tt>Pointcut</tt></i>)</tt></td><td> |
| The aspect is defined for each entrance to the control flow |
| below the join points defined by <i><tt>Pointcut</tt></i>. |
| </td><td><tt>aspectOf()</tt> at join points in |
| <tt>cflowbelow(<i><tt>Pointcut</tt></i>)</tt></td></tr></tbody></table></div></div></div><div class="appendix"><div class="titlepage"><div><h2 class="title"><a name="semantics"></a>Appendix B. Language Semantics</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#semantics-intro">Introduction</a></dt><dt><a href="#semantics-joinPoints">Join Points</a></dt><dt><a href="#semantics-pointcuts">Pointcuts</a></dt><dd><dl><dt><a href="#pointcut-definition">Pointcut definition</a></dt><dt><a href="#context-exposure">Context exposure</a></dt><dt><a href="#primitive-pointcuts">Primitive pointcuts</a></dt><dt><a href="#signatures">Signatures</a></dt><dt><a href="#matching">Matching</a></dt><dt><a href="#type-patterns">Type patterns</a></dt><dt><a href="#pattern-summary">Pattern Summary</a></dt></dl></dd><dt><a href="#semantics-advice">Advice</a></dt><dd><dl><dt><a href="#advice-modifiers">Advice modifiers</a></dt><dt><a href="#advice-and-checked-exceptions">Advice and checked exceptions</a></dt><dt><a href="#advice-precedence">Advice precedence</a></dt><dt><a href="#reflective-access-to-the-join-point">Reflective access to the join point</a></dt></dl></dd><dt><a href="#semantics-declare">Static crosscutting</a></dt><dd><dl><dt><a href="#inter-type-member-declarations">Inter-type member declarations</a></dt><dt><a href="#access-modifiers">Access modifiers</a></dt><dt><a href="#conflicts">Conflicts</a></dt><dt><a href="#extension-and-implementation">Extension and Implementation</a></dt><dt><a href="#interfaces-with-members">Interfaces with members</a></dt><dt><a href="#warnings-and-errors">Warnings and Errors</a></dt><dt><a href="#softened-exceptions">Softened exceptions</a></dt><dt><a href="#advice-precedence">Advice Precedence</a></dt><dt><a href="#statically-determinable-pointcuts">Statically determinable pointcuts</a></dt></dl></dd><dt><a href="#semantics-aspects">Aspects</a></dt><dd><dl><dt><a href="#aspect-declaration">Aspect Declaration</a></dt><dt><a href="#aspect-extension">Aspect Extension</a></dt><dt><a href="#aspect-instantiation">Aspect instantiation</a></dt><dt><a href="#aspect-privilege">Aspect privilege</a></dt></dl></dd></dl></div><div class="sect1"><a name="semantics-intro"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="semantics-intro"></a>Introduction</h2></div></div><p> |
| AspectJ extends Java by overlaying a concept of join points onto the |
| existing Java semantics and adding a few new program elements to Java: |
| </p><p> |
| A join point is a well-defined point in the execution of a |
| program. These include method and constructor calls, field accesses and |
| others described below. |
| </p><p> |
| A pointcut picks out join points, and exposes some of the values in the |
| execution context of those join points. There are several primitive |
| pointcut designators, and others can be named and defined by the |
| <tt>pointcut</tt> declaration. |
| </p><p> |
| A piece of advice is code that executes at each join point in a |
| pointcut. Advice has access to the values exposed by the |
| pointcut. Advice is defined by <tt>before</tt>, |
| <tt>after</tt>, and <tt>around</tt> declarations. |
| </p><p> |
| Inter-type declarations form AspectJ's static crosscutting features, |
| that is, is code that may change the type structure of a program, by |
| adding to or extending interfaces and classes with new fields, |
| constructors, or methods. Some inter-type declarations are defined |
| through an extension of usual method, field, and constructor |
| declarations, and other declarations are made with a new |
| <tt>declare</tt> keyword. |
| </p><p> |
| An aspect is a crosscutting type that encapsulates pointcuts, advice, |
| and static crosscutting features. By type, we mean Java's notion: a |
| modular unit of code, with a well-defined interface, about which it is |
| possible to do reasoning at compile time. Aspects are defined by the |
| <tt>aspect</tt> declaration. |
| </p></div><div class="sect1"><a name="semantics-joinPoints"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="semantics-joinPoints"></a>Join Points</h2></div></div><p> |
| While aspects define types that crosscut, the AspectJ system does not |
| allow completely arbitrary crosscutting. Rather, aspects define types |
| that cut across principled points in a program's execution. These |
| principled points are called join points. |
| </p><p> |
| A join point is a well-defined point in the execution of a |
| program. The join points defined by AspectJ are: |
| </p><div class="variablelist"><dl><dt><a name="d0e4541"></a><span class="term">Method call</span></dt><dd> |
| When a method is called, not including super calls of |
| non-static methods. |
| </dd><dt><a name="d0e4546"></a><span class="term">Method execution</span></dt><dd> |
| When the body of code for an actual method executes. |
| </dd><dt><a name="d0e4551"></a><span class="term">Constructor call</span></dt><dd> |
| When an object is built and that object's initial constructor is |
| called (i.e., not for "super" or "this" constructor calls). The |
| object being constructed is returned at a constructor call join |
| point, so its return type is considered to be the type of the |
| object, and the object itself may be accessed with <tt>after |
| returning</tt> advice. |
| </dd><dt><a name="d0e4559"></a><span class="term">Constructor execution</span></dt><dd> |
| When the body of code for an actual constructor executes, after |
| its this or super constructor call. The object being constructed |
| is the currently executing object, and so may be accessed with |
| the <tt>this</tt> pointcut. The constructor execution |
| join point for a constructor that calls a super constructor also |
| includes any non-static initializers of enclosing class. No |
| value is returned from a constructor execution join point, so its |
| return type is considered to be void. |
| </dd><dt><a name="d0e4567"></a><span class="term">Static initializer execution</span></dt><dd> |
| When the static initializer for a class executes. No value is |
| returned from a static initializer execution join point, so its |
| return type is considered to be void. |
| </dd><dt><a name="d0e4572"></a><span class="term">Object pre-initialization</span></dt><dd> |
| Before the object initialization code for a particular class runs. |
| This encompasses the time between the start of its first called |
| constructor and the start of its parent's constructor. Thus, the |
| execution of these join points encompass the join points of the |
| evaluation of the arguments of <tt>this()</tt> and |
| <tt>super()</tt> constructor calls. No value is |
| returned from an object pre-initialization join point, so its |
| return type is considered to be void. |
| </dd><dt><a name="d0e4583"></a><span class="term">Object initialization</span></dt><dd> |
| When the object initialization code for a particular class runs. |
| This encompasses the time between the return of its parent's |
| constructor and the return of its first called constructor. It |
| includes all the dynamic initializers and constructors used to |
| create the object. The object being constructed is the currently |
| executing object, and so may be accessed with the |
| <tt>this</tt> pointcut. No value is returned from a |
| constructor execution join point, so its return type is |
| considered to be void. |
| </dd><dt><a name="d0e4591"></a><span class="term">Field reference</span></dt><dd> |
| When a non-constant field is referenced. [Note that references |
| to constant fields (static final fields bound to a constant |
| string object or primitive value) are not join points, since Java |
| requires them to be inlined.] |
| </dd><dt><a name="d0e4596"></a><span class="term">Field set</span></dt><dd> |
| When a field is assigned to. |
| Field set join points are considered to have one argument, |
| the value the field is being set to. |
| No value is returned from a field set join point, so |
| its return type is considered to be void. |
| [Note that the initializations of constant fields (static |
| final fields where the initializer is a constant string object or |
| primitive value) are not join points, since Java requires their |
| references to be inlined.] |
| </dd><dt><a name="d0e4601"></a><span class="term">Handler execution</span></dt><dd> |
| When an exception handler executes. |
| Handler execution join points are considered to have one argument, |
| the exception being handled. |
| No value is returned from a field set join point, so |
| its return type is considered to be void. |
| </dd><dt><a name="d0e4606"></a><span class="term">Advice execution</span></dt><dd> |
| When the body of code for a piece of advice executes. |
| </dd></dl></div><p> |
| Each join point potentially has three pieces of state associated |
| with it: the currently executing object, the target object, and |
| an object array of arguments. These are exposed by the three |
| state-exposing pointcuts, <tt>this</tt>, |
| <tt>target</tt>, and <tt>args</tt>, |
| respectively. |
| </p><p> |
| Informally, the currently executing object is the object that a |
| <tt>this</tt> expression would pick out at the join |
| point. The target object is where control or attention is |
| transferred to by the join point. The arguments are those |
| values passed for that transfer of control or attention. |
| </p><div class="informaltable" id="d0e4627"><a name="d0e4627"></a><table border="1"><colgroup><col><col><col><col></colgroup><thead valign="top"><tr><th><span class="bold"><b>Join Point</b></span></th><th><span class="bold"><b>Current Object</b></span></th><th><span class="bold"><b>Target Object</b></span></th><th><span class="bold"><b>Arguments</b></span></th></tr></thead><tbody><tr><td>Method Call</td><td>executing object*</td><td>target object**</td><td>method arguments</td></tr><tr><td>Method Execution</td><td>executing object*</td><td>executing object*</td><td>method arguments</td></tr><tr><td>Constructor Call</td><td>executing object*</td><td>None</td><td>constructor arguments</td></tr><tr><td>Constructor Execution</td><td>executing object</td><td>executing object</td><td>constructor arguments</td></tr><tr><td>Static initializer execution</td><td>None</td><td>None</td><td>None</td></tr><tr><td>Object pre-initialization</td><td>None</td><td>None</td><td>constructor arguments</td></tr><tr><td>Object initialization</td><td>executing object</td><td>executing object</td><td>constructor arguments</td></tr><tr><td>Field reference</td><td>executing object*</td><td>target object**</td><td>None</td></tr><tr><td>Field assignment</td><td>executing object*</td><td>target object**</td><td>assigned value</td></tr><tr><td>Handler execution</td><td>executing object*</td><td>executing object*</td><td>caught exception</td></tr><tr><td>Advice execution</td><td>executing aspect</td><td>executing aspect</td><td>advice arguments</td></tr></tbody></table></div><p>* There is no executing object in static contexts such as |
| static method bodies or static initializers. |
| </p><p>** There is no target object for join points associated |
| with static methods or fields. |
| </p></div><div class="sect1"><a name="semantics-pointcuts"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="semantics-pointcuts"></a>Pointcuts</h2></div></div><p> |
| A pointcut is a program element that picks out join points and |
| exposes data from the execution context of those join points. |
| Pointcuts are used primarily by advice. They can be composed with |
| boolean operators to build up other pointcuts. The primitive |
| pointcuts and combinators provided by the language are: |
| </p><div class="variablelist"><dl><dt><a name="d0e4754"></a><span class="term"><tt>call(<i><tt>MethodPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each method call join point whose signature matches |
| <i><tt>MethodPattern</tt></i>. |
| </dd><dt><a name="d0e4766"></a><span class="term"><tt>execution(<i><tt>MethodPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each method execution join point whose signature matches |
| <i><tt>MethodPattern</tt></i>. |
| </dd><dt><a name="d0e4778"></a><span class="term"><tt>get(<i><tt>FieldPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each field reference join point whose signature matches |
| <i><tt>FieldPattern</tt></i>. |
| [Note that references to constant fields (static final |
| fields bound to a constant string object or primitive value) are not |
| join points, since Java requires them to be inlined.] |
| </dd><dt><a name="d0e4790"></a><span class="term"><tt>set(<i><tt>FieldPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each field set join point whose signature matches |
| <i><tt>FieldPattern</tt></i>. |
| [Note that the initializations of constant fields (static |
| final fields where the initializer is a constant string object or |
| primitive value) are not join points, since Java requires their |
| references to be inlined.] |
| </dd><dt><a name="d0e4802"></a><span class="term"><tt>call(<i><tt>ConstructorPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each constructor call join point whose signature matches |
| <i><tt>ConstructorPattern</tt></i>. |
| </dd><dt><a name="d0e4814"></a><span class="term"><tt>execution(<i><tt>ConstructorPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each constructor execution join point whose signature matches |
| <i><tt>ConstructorPattern</tt></i>. |
| </dd><dt><a name="d0e4826"></a><span class="term"><tt>initialization(<i><tt>ConstructorPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each object initialization join point whose signature matches |
| <i><tt>ConstructorPattern</tt></i>. |
| </dd><dt><a name="d0e4838"></a><span class="term"><tt>preinitialization(<i><tt>ConstructorPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each object pre-initialization join point whose signature matches |
| <i><tt>ConstructorPattern</tt></i>. |
| </dd><dt><a name="d0e4850"></a><span class="term"><tt>staticinitialization(<i><tt>TypePattern</tt></i>)</tt></span></dt><dd> |
| Picks out each static initializer execution join point whose signature matches |
| <i><tt>TypePattern</tt></i>. |
| </dd><dt><a name="d0e4862"></a><span class="term"><tt>handler(<i><tt>TypePattern</tt></i>)</tt></span></dt><dd> |
| Picks out each exception handler join point whose signature matches |
| <i><tt>TypePattern</tt></i>. |
| </dd><dt><a name="d0e4874"></a><span class="term"><tt>adviceexecution()</tt></span></dt><dd> |
| Picks out all advice execution join points. |
| </dd><dt><a name="d0e4880"></a><span class="term"><tt>within(<i><tt>TypePattern</tt></i>)</tt></span></dt><dd> |
| Picks out each join point where the executing code is defined |
| in a type matched by <i><tt>TypePattern</tt></i>. |
| </dd><dt><a name="d0e4892"></a><span class="term"><tt>withincode(<i><tt>MethodPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each join point where the executing code is defined in |
| a method whose signature matches |
| <i><tt>MethodPattern</tt></i>. |
| </dd><dt><a name="d0e4904"></a><span class="term"><tt>withincode(<i><tt>ConstructorPattern</tt></i>)</tt></span></dt><dd> |
| Picks out each join point where the executing code is defined |
| in a constructor whose signature matches |
| <i><tt>ConstructorPattern</tt></i>. |
| </dd><dt><a name="d0e4916"></a><span class="term"><tt>cflow(<i><tt>Pointcut</tt></i>)</tt></span></dt><dd> |
| Picks out each join point in the control flow of any join point |
| <i><tt>P</tt></i> picked out by |
| <i><tt>Pointcut</tt></i>, including |
| <i><tt>P</tt></i> itself. |
| </dd><dt><a name="d0e4934"></a><span class="term"><tt>cflowbelow(<i><tt>Pointcut</tt></i>)</tt></span></dt><dd> |
| Picks out each join point in the control flow of any join point |
| <i><tt>P</tt></i> picked out by |
| <i><tt>Pointcut</tt></i>, but not |
| <i><tt>P</tt></i> itself. |
| </dd><dt><a name="d0e4952"></a><span class="term"><tt>this(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>)</tt></span></dt><dd> |
| Picks out each join point where the currently executing object |
| (the object bound to <tt>this</tt>) is an instance of |
| <i><tt>Type</tt></i>, or of the type of the |
| identifier <i><tt>Id</tt></i> (which must be bound in the enclosing |
| advice or pointcut definition). |
| Will not match any join points from static contexts. |
| </dd><dt><a name="d0e4973"></a><span class="term"><tt>target(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>)</tt></span></dt><dd> |
| Picks out each join point where the target object (the object |
| on which a call or field operation is applied to) is an instance of |
| <i><tt>Type</tt></i>, or of the type of the identifier |
| <i><tt>Id</tt></i> (which must be bound in the enclosing |
| advice or pointcut definition). |
| Will not match any calls, gets, or sets of static members. |
| </dd><dt><a name="d0e4991"></a><span class="term"><tt>args(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>, ...)</tt></span></dt><dd> |
| Picks out each join point where the arguments are instances of |
| the appropriate type (or type of the identifier if using that form). A |
| <tt>null</tt> argument is matched iff the static type of the |
| argument (declared parameter type or field type) is the same as, or a subtype of, |
| the specified args type. |
| </dd><dt><a name="d0e5006"></a><span class="term"><tt><i><tt>PointcutId</tt></i>(<i><tt>TypePattern</tt></i> or <i><tt>Id</tt></i>, ...)</tt></span></dt><dd> |
| Picks out each join point that is picked out by the |
| user-defined pointcut designator named by |
| <i><tt>PointcutId</tt></i>. |
| </dd><dt><a name="d0e5023"></a><span class="term"><tt>if(<i><tt>BooleanExpression</tt></i>)</tt></span></dt><dd> |
| Picks out each join point where the boolean expression |
| evaluates to <tt>true</tt>. The boolean expression used |
| can only access static members, parameters exposed by the enclosing |
| pointcut or advice, and <tt>thisJoinPoint</tt> forms. In |
| particular, it cannot call non-static methods on the aspect or |
| use return values or exceptions exposed by after advice. |
| </dd><dt><a name="d0e5038"></a><span class="term"><tt>! <i><tt>Pointcut</tt></i></tt></span></dt><dd> |
| Picks out each join point that is not picked out by |
| <i><tt>Pointcut</tt></i>. |
| </dd><dt><a name="d0e5049"></a><span class="term"><tt><i><tt>Pointcut0</tt></i> && <i><tt>Pointcut1</tt></i></tt></span></dt><dd> |
| Picks out each join points that is picked out by both |
| <i><tt>Pointcut0</tt></i> and |
| <i><tt>Pointcut1</tt></i>. |
| </dd><dt><a name="d0e5065"></a><span class="term"><tt><i><tt>Pointcut0</tt></i> || <i><tt>Pointcut1</tt></i></tt></span></dt><dd> |
| Picks out each join point that is picked out by either |
| pointcuts. <i><tt>Pointcut0</tt></i> or |
| <i><tt>Pointcut1</tt></i>. |
| </dd><dt><a name="d0e5081"></a><span class="term"><tt>( <i><tt>Pointcut</tt></i> )</tt></span></dt><dd> |
| Picks out each join points picked out by |
| <i><tt>Pointcut</tt></i>. |
| </dd></dl></div><div class="sect2"><a name="pointcut-definition"></a><div class="titlepage"><div><h3 class="title"><a name="pointcut-definition"></a>Pointcut definition</h3></div></div><p> |
| Pointcuts are defined and named by the programmer with the |
| <tt>pointcut</tt> declaration. |
| </p><pre class="programlisting"> |
| pointcut publicIntCall(int i): |
| call(public * *(int)) && args(i); |
| </pre><p> |
| A named pointcut may be defined in either a class or aspect, and is |
| treated as a member of the class or aspect where it is found. As a |
| member, it may have an access modifier such as |
| <tt>public</tt> or <tt>private</tt>. |
| </p><pre class="programlisting"> |
| class C { |
| pointcut publicCall(int i): |
| call(public * *(int)) && args(i); |
| } |
| |
| class D { |
| pointcut myPublicCall(int i): |
| C.publicCall(i) && within(SomeType); |
| } |
| </pre><p> |
| Pointcuts that are not final may be declared abstract, and defined |
| without a body. Abstract pointcuts may only be declared within |
| abstract aspects. |
| </p><pre class="programlisting"> |
| abstract aspect A { |
| abstract pointcut publicCall(int i); |
| } |
| </pre><p> |
| In such a case, an extending aspect may override the abstract |
| pointcut. |
| </p><pre class="programlisting"> |
| aspect B extends A { |
| pointcut publicCall(int i): call(public Foo.m(int)) && args(i); |
| } |
| </pre><p> |
| For completeness, a pointcut with a declaration may be declared |
| <tt>final</tt>. |
| </p><p> |
| Though named pointcut declarations appear somewhat like method |
| declarations, and can be overridden in subaspects, they cannot be |
| overloaded. It is an error for two pointcuts to be named with the |
| same name in the same class or aspect declaration. |
| </p><p> |
| The scope of a named pointcut is the enclosing class declaration. |
| This is different than the scope of other members; the scope of |
| other members is the enclosing class <span class="emphasis"><i>body</i></span>. |
| This means that the following code is legal: |
| </p><pre class="programlisting"> |
| aspect B percflow(publicCall()) { |
| pointcut publicCall(): call(public Foo.m(int)); |
| } |
| </pre></div><div class="sect2"><a name="context-exposure"></a><div class="titlepage"><div><h3 class="title"><a name="context-exposure"></a>Context exposure</h3></div></div><p> |
| Pointcuts have an interface; they expose some parts of the |
| execution context of the join points they pick out. For example, |
| the PublicIntCall above exposes the first argument from the |
| receptions of all public unary integer methods. This context is |
| exposed by providing typed formal parameters to named pointcuts and |
| advice, like the formal parameters of a Java method. These formal |
| parameters are bound by name matching. |
| </p><p> |
| On the right-hand side of advice or pointcut declarations, in |
| certain pointcut designators, a Java identifier is allowed in place |
| of a type or collection of types. The pointcut designators that |
| allow this are <tt>this</tt>, <tt>target</tt>, |
| and <tt>args</tt>. In all such cases, using an |
| identifier rather than a type does two things. First, it selects |
| join points as based on the type of the formal parameter. So the |
| pointcut |
| </p><pre class="programlisting"> |
| pointcut intArg(int i): args(i); |
| </pre><p> |
| picks out join points where an <tt>int</tt> (or |
| a <tt>byte</tt>, <tt>short</tt>, or |
| <tt>char</tt>; anything assignable to an |
| <tt>int</tt>) is being passed as an argument. |
| Second, though, it makes the value of that argument |
| available to the enclosing advice or pointcut. |
| </p><p> |
| Values can be exposed from named pointcuts as well, so |
| </p><pre class="programlisting"> |
| pointcut publicCall(int x): call(public *.*(int)) && intArg(x); |
| pointcut intArg(int i): args(i); |
| </pre><p> |
| is a legal way to pick out all calls to public methods accepting an |
| int argument, and exposing that argument. |
| </p><p> |
| There is one special case for this kind of exposure. Exposing an |
| argument of type Object will also match primitive typed arguments, |
| and expose a "boxed" version of the primitive. So, |
| </p><pre class="programlisting"> |
| pointcut publicCall(): call(public *.*(..)) && args(Object); |
| </pre><p> |
| will pick out all unary methods that take, as their only argument, |
| subtypes of Object (i.e., not primitive types like |
| <tt>int</tt>), but |
| </p><pre class="programlisting"> |
| pointcut publicCall(Object o): call(public *.*(..)) && args(o); |
| </pre><p> |
| will pick out all unary methods that take any argument: And if the |
| argument was an <tt>int</tt>, then the value passed to |
| advice will be of type <tt>java.lang.Integer</tt>. |
| </p><p> |
| The "boxing" of the primitive value is based on the |
| <span class="emphasis"><i>original</i></span> primitive type. So in the |
| following program |
| </p><pre class="programlisting"> |
| public class InstanceOf { |
| |
| public static void main(String[] args) { |
| doInt(5); |
| } |
| |
| static void doInt(int i) { } |
| } |
| |
| aspect IntToLong { |
| pointcut el(long l) : |
| execution(* doInt(..)) && args(l); |
| |
| before(Object o) : el(o) { |
| System.out.println(o.getClass()); |
| } |
| } |
| </pre><p> |
| The pointcut will match and expose the integer argument, |
| but it will expose it as an <tt>Integer</tt>, |
| not a <tt>Long</tt>. |
| </p></div><div class="sect2"><a name="primitive-pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="primitive-pointcuts"></a>Primitive pointcuts</h3></div></div><div class="sect3"><a name="d0e5213"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5213"></a>Method-related pointcuts</h4></div></div><p>AspectJ provides two primitive pointcut designators designed to |
| capture method call and execution join points. </p><div class="itemizedlist"><ul><li><a name="d0e5219"></a><tt>call(<i><tt>MethodPattern</tt></i>)</tt></li><li><a name="d0e5225"></a><tt>execution(<i><tt>MethodPattern</tt></i>)</tt></li></ul></div></div><div class="sect3"><a name="d0e5231"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5231"></a>Field-related pointcuts</h4></div></div><p> |
| AspectJ provides two primitive pointcut designators designed to |
| capture field reference and set join points: |
| </p><div class="itemizedlist"><ul><li><a name="d0e5237"></a><tt>get(<i><tt>FieldPattern</tt></i>)</tt></li><li><a name="d0e5243"></a><tt>set(<i><tt>FieldPattern</tt></i>)</tt></li></ul></div><p> |
| All set join points are treated as having one argument, the value the |
| field is being set to, so at a set join point, that value can be |
| accessed with an <tt>args</tt> pointcut. So an aspect |
| guarding a static integer variable x declared in type T might be written as |
| </p><pre class="programlisting"> |
| aspect GuardedX { |
| static final int MAX_CHANGE = 100; |
| before(int newval): set(static int T.x) && args(newval) { |
| if (Math.abs(newval - T.x) > MAX_CHANGE) |
| throw new RuntimeException(); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e5256"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5256"></a>Object creation-related pointcuts</h4></div></div><p> |
| AspectJ provides primitive pointcut designators designed to |
| capture the initializer execution join points of objects. |
| </p><div class="itemizedlist"><ul><li><a name="d0e5262"></a><tt>call(<i><tt>ConstructorPattern</tt></i>)</tt></li><li><a name="d0e5268"></a><tt>execution(<i><tt>ConstructorPattern</tt></i>)</tt></li><li><a name="d0e5274"></a><tt>initialization(<i><tt>ConstructorPattern</tt></i>)</tt></li><li><a name="d0e5280"></a><tt>preinitialization(<i><tt>ConstructorPattern</tt></i>)</tt></li></ul></div></div><div class="sect3"><a name="d0e5286"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5286"></a>Class initialization-related pointcuts</h4></div></div><p> |
| AspectJ provides one primitive pointcut designator to pick out |
| static initializer execution join points. |
| </p><div class="itemizedlist"><ul><li><a name="d0e5292"></a><tt>staticinitialization(<i><tt>TypePattern</tt></i>)</tt></li></ul></div></div><div class="sect3"><a name="d0e5298"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5298"></a>Exception handler execution-related pointcuts</h4></div></div><p> |
| AspectJ provides one primitive pointcut designator to capture |
| execution of exception handlers: |
| </p><div class="itemizedlist"><ul><li><a name="d0e5304"></a><tt>handler(<i><tt>TypePattern</tt></i>)</tt></li></ul></div><p> |
| All handler join points are treated as having one argument, the value |
| of the exception being handled. That value can be accessed with an |
| <tt>args</tt> pointcut. So an aspect used to put |
| <tt>FooException</tt> objects into some normal form before |
| they are handled could be written as |
| </p><pre class="programlisting"> |
| aspect NormalizeFooException { |
| before(FooException e): handler(FooException) && args(e) { |
| e.normalize(); |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e5320"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5320"></a>Advice execution-related pointcuts</h4></div></div><p> |
| AspectJ provides one primitive pointcut designator to capture |
| execution of advice |
| </p><div class="itemizedlist"><ul><li><a name="d0e5326"></a><tt>adviceexecution()</tt></li></ul></div><p> |
| This can be used, for example, to filter out any join point in the |
| control flow of advice from a particular aspect. |
| </p><pre class="programlisting"> |
| aspect TraceStuff { |
| pointcut myAdvice(): adviceexecution() && within(TraceStuff); |
| |
| before(): call(* *(..)) && !cflow(myAdvice) { |
| // do something |
| } |
| } |
| </pre></div><div class="sect3"><a name="d0e5333"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5333"></a>State-based pointcuts</h4></div></div><p> |
| Many concerns cut across the dynamic times when an object of a |
| particular type is executing, being operated on, or being passed |
| around. AspectJ provides primitive pointcuts that capture join |
| points at these times. These pointcuts use the dynamic types of |
| their objects to pick out join points. They may also be used to |
| expose the objects used for discrimination. |
| </p><div class="itemizedlist"><ul><li><a name="d0e5339"></a><tt>this(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>)</tt></li><li><a name="d0e5348"></a><tt>target(<i><tt>Type</tt></i> or <i><tt>Id</tt></i>)</tt></li></ul></div><p> |
| The <tt>this</tt> pointcut picks out each join point where |
| the currently executing object (the object bound to |
| <tt>this</tt>) is an instance of a particular type. The |
| <tt>target</tt> pointcut picks out each join point where |
| the target object (the object on which a method is called or a field |
| is accessed) is an instance of a particular type. Note that |
| <tt>target</tt> should be understood to be the object the |
| current join point is transfering control to. This means that the |
| target object is the same as the current object at a method execution |
| join point, for example, but may be different at a method call join |
| point. |
| </p><div class="itemizedlist"><ul><li><a name="d0e5372"></a><tt>args(<i><tt>Type</tt></i> or <i><tt>Id</tt></i> or "..", ...)</tt></li></ul></div><p> |
| The args pointcut picks out each join point where the arguments are |
| instances of some types. Each element in the comma-separated list is |
| one of four things. If it is a type name, then the argument in that |
| position must be an instance of that type. If it is an identifier, |
| then that identifier must be bound in the enclosing advice or |
| pointcut declaration, and so the argument in that position must be an |
| instance of the type of the identifier (or of any type if the |
| identifier is typed to Object). If it is the "*" wildcard, then any |
| argument will match, and if it is the special wildcard "..", then any |
| number of arguments will match, just like in signature patterns. So the |
| pointcut |
| </p><pre class="programlisting"> |
| args(int, .., String) |
| </pre><p> |
| will pick out all join points where the first argument is an |
| <tt>int</tt> and the last is a <tt>String</tt>. |
| </p></div><div class="sect3"><a name="d0e5393"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5393"></a>Control flow-based pointcuts</h4></div></div><p> |
| Some concerns cut across the control flow of the program. The |
| <tt>cflow</tt> and <tt>cflowbelow</tt> primitive |
| pointcut designators capture join points based on control flow. |
| </p><div class="itemizedlist"><ul><li><a name="d0e5405"></a><tt>cflow(<i><tt>Pointcut</tt></i>)</tt></li><li><a name="d0e5411"></a><tt>cflowbelow(<i><tt>Pointcut</tt></i>)</tt></li></ul></div><p> |
| The <tt>cflow</tt> pointcut picks out all join points that |
| occur between entry and exit of each join point |
| <i><tt>P</tt></i> picked out by |
| <i><tt>Pointcut</tt></i>, including |
| <i><tt>P</tt></i> itself. Hence, it picks out the join |
| points <span class="emphasis"><i>in</i></span> the control flow of the join points |
| picked out by <i><tt>Pointcut</tt></i>. |
| </p><p> |
| The <tt>cflowbelow</tt> pointcut picks out all join points |
| that occur between entry and exit of each join point |
| <i><tt>P</tt></i> picked out by |
| <i><tt>Pointcut</tt></i>, but not including |
| <i><tt>P</tt></i> itself. Hence, it picks out the join |
| points <span class="emphasis"><i>below</i></span> the control flow of the join points |
| picked out by <i><tt>Pointcut</tt></i>. |
| </p><div class="sect4"><a name="d0e5457"></a><div class="titlepage"><div><h5 class="title"><a name="d0e5457"></a>Context exposure from control flows</h5></div></div><p> |
| The <tt>cflow</tt> and |
| <tt>cflowbelow</tt> pointcuts may expose context |
| state through enclosed <tt>this</tt>, |
| <tt>target</tt>, and <tt>args</tt> |
| pointcuts. |
| </p><p> |
| Anytime such state is accessed, it is accessed through the |
| <span class="emphasis"><i>most recent</i></span> control flow that |
| matched. So the "current arg" that would be printed by |
| the following program is zero, even though it is in many |
| control flows. |
| </p><pre class="programlisting"> |
| class Test { |
| public static void main(String[] args) { |
| fact(5); |
| } |
| static int fact(int x) { |
| if (x == 0) { |
| System.err.println("bottoming out"); |
| return 1; |
| } |
| else return x * fact(x - 1); |
| } |
| } |
| |
| aspect A { |
| pointcut entry(int i): call(int fact(int)) && args(i); |
| pointcut writing(): call(void println(String)) && ! within(A); |
| |
| before(int i): writing() && cflow(entry(i)) { |
| System.err.println("Current arg is " + i); |
| } |
| } |
| </pre><p> |
| It is an error to expose such state through |
| <span class="emphasis"><i>negated</i></span> control flow pointcuts, such |
| as within <tt>! |
| cflowbelow(<i><tt>P</tt></i>)</tt>. |
| </p></div></div><div class="sect3"><a name="d0e5495"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5495"></a>Program text-based pointcuts</h4></div></div><p> |
| While many concerns cut across the runtime structure of the program, |
| some must deal with the lexical structure. AspectJ allows aspects to |
| pick out join points based on where their associated code is defined. |
| </p><div class="itemizedlist"><ul><li><a name="d0e5501"></a><tt>within(<i><tt>TypePattern</tt></i>)</tt></li><li><a name="d0e5507"></a><tt>withincode(<i><tt>MethodPattern</tt></i>)</tt></li><li><a name="d0e5513"></a><tt>withincode(<i><tt>ConstructorPattern</tt></i>)</tt></li></ul></div><p> |
| The <tt>within</tt> pointcut picks out each join point |
| where the code executing is defined in the declaration of one of the |
| types in <i><tt>TypePattern</tt></i>. This includes the |
| class initialization, object initialization, and method and |
| constructor execution join points for the type, as well as any join |
| points associated with the statements and expressions of the type. |
| It also includes any join points that are associated with code in a |
| type's nested types, and that type's default constructor, if there is |
| one. |
| </p><p> |
| The <tt>withincode</tt> pointcuts picks out each join point |
| where the code executing is defined in the declaration of a |
| particular method or constructor. This includes the method or |
| constructor execution join point as well as any join points |
| associated with the statements and expressions of the method or |
| constructor. It also includes any join points that are associated |
| with code in a method or constructor's local or anonymous types. |
| </p></div><div class="sect3"><a name="d0e5532"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5532"></a>Expression-based pointcuts</h4></div></div><div class="itemizedlist"><ul><li><a name="d0e5536"></a><tt>if(<i><tt>BooleanExpression</tt></i>)</tt></li></ul></div><p> |
| The if pointcut picks out join points based on a dynamic property. |
| It's syntax takes an expression, which must evaluate to a boolean |
| true or false. Within this expression, the |
| <tt>thisJoinPoint</tt> object is available. So one |
| (extremely inefficient) way of picking out all call join points would |
| be to use the pointcut |
| </p><pre class="programlisting"> |
| if(thisJoinPoint.getKind().equals("call")) |
| </pre><p> |
| Note that the order of evaluation for pointcut expression |
| components at a join point is undefined. Writing <tt>if</tt> |
| pointcuts that have side-effects is considered bad style and may also |
| lead to potentially confusing or even changing behavior with regard |
| to when or if the test code will run. |
| </p></div></div><div class="sect2"><a name="signatures"></a><div class="titlepage"><div><h3 class="title"><a name="signatures"></a>Signatures</h3></div></div><p> |
| One very important property of a join point is its signature, which is |
| used by many of AspectJ's pointcut designators to select particular |
| join points. |
| </p><div class="sect3"><a name="d0e5559"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5559"></a>Methods</h4></div></div><p> |
| Join points associated with methods typically have method signatures, |
| consisting of a method name, parameter types, return type, the types of |
| the declared (checked) exceptions, and some type that the method could |
| be called on (below called the "qualifying type"). |
| </p><p> |
| At a method call join point, the signature is a method signature whose |
| qualifying type is the static type used to <span class="emphasis"><i>access</i></span> |
| the method. This means that the signature for the join point created |
| from the call <tt>((Integer)i).toString()</tt> is different |
| than that for the call <tt>((Object)i).toString()</tt>, even |
| if <tt>i</tt> is the same variable. |
| </p><p> |
| At a method execution join point, the signature is a method signature |
| whose qualifying type is the declaring type of the method. |
| </p></div><div class="sect3"><a name="d0e5580"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5580"></a>Fields</h4></div></div><p> |
| Join points associated with fields typically have field signatures, |
| consisting of a field name and a field type. A field reference join |
| point has such a signature, and no parameters. A field set join point |
| has such a signature, but has a has a single parameter whose type is |
| the same as the field type. |
| </p></div><div class="sect3"><a name="d0e5585"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5585"></a>Constructors</h4></div></div><p> |
| Join points associated with constructors typically have constructor |
| signatures, consisting of a parameter types, the types of the declared |
| (checked) exceptions, and the declaring type. |
| </p><p> |
| At a constructor call join point, the signature is the constructor |
| signature of the called constructor. At a constructor execution join |
| point, the signature is the constructor signature of the currently |
| executing constructor. |
| </p><p> |
| At object initialization and pre-initialization join points, the |
| signature is the constructor signature for the constructor that started |
| this initialization: the first constructor entered during this type's |
| initialization of this object. |
| </p></div><div class="sect3"><a name="d0e5594"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5594"></a>Others</h4></div></div><p> |
| At a handler execution join point, the signature is composed of the |
| exception type that the handler handles. |
| </p><p> |
| At an advice execution join point, the signature is composed of the |
| aspect type, the parameter types of the advice, the return type (void |
| for all but around advice) and the types of the declared (checked) |
| exceptions. |
| </p></div></div><div class="sect2"><a name="matching"></a><div class="titlepage"><div><h3 class="title"><a name="matching"></a>Matching</h3></div></div><p> |
| The <tt>withincode</tt>, <tt>call</tt>, |
| <tt>execution</tt>, <tt>get</tt>, and |
| <tt>set</tt> primitive pointcut designators all use signature |
| patterns to determine the join points they describe. A signature |
| pattern is an abstract description of one or more join-point |
| signatures. Signature patterns are intended to match very closely the |
| same kind of things one would write when declaring individual members |
| and constructors. |
| </p><p> |
| Method declarations in Java include method names, method parameters, |
| return types, modifiers like static or private, and throws clauses, |
| while constructor declarations omit the return type and replace the |
| method name with the class name. The start of a particular method |
| declaration, in class <tt>Test</tt>, for example, might be |
| </p><pre class="programlisting"> |
| class C { |
| public final void foo() throws ArrayOutOfBoundsException { ... } |
| } |
| </pre><p> |
| In AspectJ, method signature patterns have all these, but most elements |
| can be replaced by wildcards. So |
| </p><pre class="programlisting"> |
| call(public final void C.foo() throws ArrayOutOfBoundsException) |
| </pre><p> |
| picks out call join points to that method, and the pointcut |
| </p><pre class="programlisting"> |
| call(public final void *.*() throws ArrayOutOfBoundsException) |
| </pre><p> |
| picks out all call join points to methods, regardless of their name |
| name or which class they are defined on, so long as they take no |
| arguments, return no value, are both <tt>public</tt> and |
| <tt>final</tt>, and are declared to throw |
| <tt>ArrayOutOfBounds</tt> exceptions. |
| </p><p> |
| The defining type name, if not present, defaults to *, so another way |
| of writing that pointcut would be |
| </p><pre class="programlisting"> |
| call(public final void *() throws ArrayOutOfBoundsException) |
| </pre><p> |
| The wildcard <tt>..</tt> indicates zero or more |
| parameters, so |
| </p><pre class="programlisting"> |
| execution(void m(..)) |
| </pre><p> |
| picks out execution join points for void methods named |
| <tt>m</tt>, of any number of arguments, while |
| </p><pre class="programlisting"> |
| execution(void m(.., int)) |
| </pre><p> |
| picks out execution join points for void methods named |
| <tt>m</tt> whose last parameter is of type |
| <tt>int</tt>. |
| </p><p> |
| The modifiers also form part of the signature pattern. If an AspectJ |
| signature pattern should match methods without a particular modifier, |
| such as all non-public methods, the appropriate modifier should be |
| negated with the <tt>!</tt> operator. So, |
| </p><pre class="programlisting"> |
| withincode(!public void foo()) |
| </pre><p> |
| picks out all join points associated with code in null non-public |
| void methods named <tt>foo</tt>, while |
| </p><pre class="programlisting"> |
| withincode(void foo()) |
| </pre><p> |
| picks out all join points associated with code in null void methods |
| named <tt>foo</tt>, regardless of access modifier. |
| </p><p> |
| Method names may contain the * wildcard, indicating any number of |
| characters in the method name. So |
| </p><pre class="programlisting"> |
| call(int *()) |
| </pre><p> |
| picks out all call join points to <tt>int</tt> methods |
| regardless of name, but |
| </p><pre class="programlisting"> |
| call(int get*()) |
| </pre><p> |
| picks out all call join points to <tt>int</tt> methods |
| where the method name starts with the characters "get". |
| </p><p> |
| AspectJ uses the <tt>new</tt> keyword for constructor |
| signature patterns rather than using a particular class name. So the |
| execution join points of private null constructor of a class C |
| defined to throw an ArithmeticException can be picked out with |
| </p><pre class="programlisting"> |
| execution(private C.new() throws ArithmeticException) |
| </pre><div class="sect3"><a name="d0e5716"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5716"></a>Matching based on the declaring type</h4></div></div><p> |
| The signature-matching pointcuts all specify a declaring type, |
| but the meaning varies slightly for each join point signature, |
| in line with Java semantics. |
| </p><p> |
| When matching for pointcuts <tt>withincode</tt>, |
| <tt>get</tt>, and <tt>set</tt>, the declaring |
| type is the class that contains the declaration. |
| </p><p> |
| When matching method-call join points, the |
| declaring type is the static type used to access the method. |
| A common mistake is to specify a declaring type for the |
| <tt>call</tt> pointcut that is a subtype of the |
| originally-declaring type. For example, given the class |
| </p><pre class="programlisting"> |
| class Service implements Runnable { |
| public void run() { ... } |
| } |
| </pre><p> |
| the following pointcut |
| </p><pre class="programlisting"> |
| call(void Service.run()) |
| </pre><p> |
| would fail to pick out the join point for the code |
| </p><pre class="programlisting"> |
| ((Runnable) new Service()).run(); |
| </pre><p> |
| Specifying the originally-declaring type is correct, but would |
| pick out any such call (here, calls to the <tt>run()</tt> |
| method of any Runnable). |
| In this situation, consider instead picking out the target type: |
| </p><pre class="programlisting"> |
| call(void run()) && target(Service) |
| </pre><p> |
| When matching method-execution join points, |
| if the execution pointcut method signature specifies a declaring type, |
| the pointcut will only match methods declared in that type, or methods |
| that override methods declared in or inherited by that type. |
| So the pointcut |
| </p><pre class="programlisting"> |
| execution(public void Middle.*()) |
| </pre><p> |
| picks out all method executions for public methods returning void |
| and having no arguments that are either declared in, or inherited by, |
| Middle, even if those methods are overridden in a subclass of Middle. |
| So the pointcut would pick out the method-execution join point |
| for Sub.m() in this code: |
| </p><pre class="programlisting"> |
| class Super { |
| protected void m() { ... } |
| } |
| class Middle extends Super { |
| } |
| class Sub extends Middle { |
| public void m() { ... } |
| } |
| </pre></div><div class="sect3"><a name="d0e5762"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5762"></a>Matching based on the throws clause</h4></div></div><p> |
| Type patterns may be used to pick out methods and constructors |
| based on their throws clauses. This allows the following two |
| kinds of extremely wildcarded pointcuts: |
| </p><pre class="programlisting"> |
| pointcut throwsMathlike(): |
| // each call to a method with a throws clause containing at least |
| // one exception exception with "Math" in its name. |
| call(* *(..) throws *..*Math*); |
| |
| pointcut doesNotThrowMathlike(): |
| // each call to a method with a throws clause containing no |
| // exceptions with "Math" in its name. |
| call(* *(..) throws !*..*Math*); |
| </pre><p> |
| A <i><tt>ThrowsClausePattern</tt></i> is a comma-separated list of |
| <i><tt>ThrowsClausePatternItem</tt></i>s, where |
| |
| <div class="variablelist"><dl><dt><a name="d0e5778"></a><span class="term"><i><tt>ThrowsClausePatternItem</tt></i> :</span></dt><dd><tt>[ ! ] |
| <i><tt>TypeNamePattern</tt></i></tt></dd></dl></div> |
| </p><p> |
| A <i><tt>ThrowsClausePattern</tt></i> matches the |
| throws clause of any code member signature. To match, each |
| <tt>ThrowsClausePatternItem</tt> must |
| match the throws clause of the member in question. If any item |
| doesn't match, then the whole pattern doesn't match. |
| </p><p> |
| If a ThrowsClausePatternItem begins with "!", then it matches a |
| particular throws clause if and only if <span class="emphasis"><i>none</i></span> |
| of the types named in the throws clause is matched by the |
| <tt>TypeNamePattern</tt>. |
| </p><p> |
| If a <i><tt>ThrowsClausePatternItem</tt></i> does not |
| begin with "!", then it matches a throws clause if and only if |
| <span class="emphasis"><i>any</i></span> of the types named in the throws clause |
| is matched by the <span class="emphasis"><i>TypeNamePattern</i></span>. |
| </p><p> |
| The rule for "!" matching has one potentially surprising |
| property, in that these two pointcuts |
| |
| <div class="itemizedlist"><ul><li><a name="d0e5819"></a> call(* *(..) throws !IOException) </li><li><a name="d0e5821"></a> call(* *(..) throws (!IOException)) </li></ul></div> |
| |
| will match differently on calls to |
| |
| <blockquote class="blockquote"><tt> |
| void m() throws RuntimeException, IOException {} |
| </tt></blockquote> |
| </p><p> |
| [1] will NOT match the method m(), because method m's throws |
| clause declares that it throws IOException. [2] WILL match the |
| method m(), because method m's throws clause declares the it |
| throws some exception which does not match IOException, |
| i.e. RuntimeException. |
| </p></div></div><div class="sect2"><a name="type-patterns"></a><div class="titlepage"><div><h3 class="title"><a name="type-patterns"></a>Type patterns</h3></div></div><p> |
| Type patterns are a way to pick out collections of types and use them |
| in places where you would otherwise use only one type. The rules for |
| using type patterns are simple. |
| </p><div class="sect3"><a name="d0e5835"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5835"></a>Exact type pattern</h4></div></div><p> |
| First, all type names are also type patterns. So |
| <tt>Object</tt>, <tt>java.util.HashMap</tt>, |
| <tt>Map.Entry</tt>, <tt>int</tt> are all type |
| patterns. |
| </p><p> |
| If a type pattern is an exact type - if it doesn't |
| include a wildcard - then the matching works just |
| like normal type lookup in Java: </p><div class="itemizedlist"><ul><li><a name="d0e5855"></a>Patterns that have the same names as |
| primitive types (like <tt>int</tt>) match |
| those primitive types.</li><li><a name="d0e5860"></a>Patterns that are qualified by package names |
| (like <tt>java.util.HashMap</tt>) match types |
| in other packages. |
| </li><li><a name="d0e5865"></a>Patterns that are not qualified (like |
| <tt>HashMap</tt>) match types that are |
| resolved by Java's normal scope rules. So, for |
| example, <tt>HashMap</tt> might match a |
| package-level type in the same package or a type that |
| have been imported with java's |
| <tt>import</tt> form. But it would not match |
| <tt>java.util.HashMap</tt> unless the aspect |
| were in <tt>java.util</tt> or the type had |
| been imported. |
| </li></ul></div><p> |
| So exact type patterns match based on usual Java scope |
| rules. |
| </p></div><div class="sect3"><a name="d0e5884"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5884"></a>Type name patterns</h4></div></div><p> |
| There is a special type name, *, which is also a type pattern. * picks out all |
| types, including primitive types. So |
| </p><pre class="programlisting"> |
| call(void foo(*)) |
| </pre><p> |
| picks out all call join points to void methods named foo, taking one |
| argument of any type. |
| </p><p> |
| Type names that contain the two wildcards "*" and |
| "<tt>..</tt>" are also type patterns. The * wildcard matches |
| zero or more characters characters except for ".", so it can be used |
| when types have a certain naming convention. So |
| </p><pre class="programlisting"> |
| handler(java.util.*Map) |
| </pre><p> |
| picks out the types java.util.Map and java.util.java.util.HashMap, |
| among others, and |
| </p><pre class="programlisting"> |
| handler(java.util.*) |
| </pre><p> |
| picks out all types that start with "<tt>java.util.</tt>" and |
| don't have any more "."s, that is, the types in the |
| <tt>java.util</tt> package, but not inner types |
| (such as java.util.Map.Entry). |
| </p><p> |
| The "<tt>..</tt>" wildcard matches any sequence of |
| characters that start and end with a ".", so it can be used |
| to pick out all types in any subpackage, or all inner types. So |
| </p><pre class="programlisting"> |
| within(com.xerox..*) |
| </pre><p> |
| picks out all join points where the code is in any |
| declaration of a type whose name begins with "<tt>com.xerox.</tt>". |
| </p><p> |
| Type patterns with wildcards do not depend on Java's |
| usual scope rules - they match against all types |
| available to the weaver, not just those that are |
| imported into an Aspect's declaring file. |
| </p></div><div class="sect3"><a name="d0e5926"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5926"></a>Subtype patterns</h4></div></div><p> |
| It is possible to pick out all subtypes of a type (or a collection of |
| types) with the "+" wildcard. The "+" wildcard follows immediately a |
| type name pattern. So, while |
| </p><pre class="programlisting"> |
| call(Foo.new()) |
| </pre><p> |
| picks out all constructor call join points where an instance of exactly |
| type Foo is constructed, |
| </p><pre class="programlisting"> |
| call(Foo+.new()) |
| </pre><p> |
| picks out all constructor call join points where an instance of any |
| subtype of Foo (including Foo itself) is constructed, and the unlikely |
| </p><pre class="programlisting"> |
| call(*Handler+.new()) |
| </pre><p> |
| picks out all constructor call join points where an instance of any |
| subtype of any type whose name ends in "Handler" is constructed. |
| </p></div><div class="sect3"><a name="d0e5943"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5943"></a>Array type patterns</h4></div></div><p> |
| A type name pattern or subtype pattern can be followed by one or more |
| sets of square brackets to make array type patterns. So |
| <tt>Object[]</tt> is an array type pattern, and so is |
| <tt>com.xerox..*[][]</tt>, and so is |
| <tt>Object+[]</tt>. |
| </p></div><div class="sect3"><a name="d0e5957"></a><div class="titlepage"><div><h4 class="title"><a name="d0e5957"></a>Type patterns</h4></div></div><p> |
| Type patterns are built up out of type name patterns, subtype patterns, |
| and array type patterns, and constructed with boolean operators |
| <tt>&&</tt>, <tt>||</tt>, and |
| <tt>!</tt>. So |
| </p><pre class="programlisting"> |
| staticinitialization(Foo || Bar) |
| </pre><p> |
| picks out the static initializer execution join points of either Foo or Bar, |
| and |
| </p><pre class="programlisting"> |
| call((Foo+ && ! Foo).new(..)) |
| </pre><p> |
| picks out the constructor call join points when a subtype of Foo, but |
| not Foo itself, is constructed. |
| </p></div></div><div class="sect2"><a name="pattern-summary"></a><div class="titlepage"><div><h3 class="title"><a name="pattern-summary"></a>Pattern Summary</h3></div></div><p> |
| Here is a summary of the pattern syntax used in AspectJ: |
| </p><pre class="programlisting"> |
| MethodPattern = |
| [ModifiersPattern] TypePattern |
| [TypePattern . ] IdPattern (TypePattern | ".." , ... ) |
| [ throws ThrowsPattern ] |
| ConstructorPattern = |
| [ModifiersPattern ] |
| [TypePattern . ] new (TypePattern | ".." , ...) |
| [ throws ThrowsPattern ] |
| FieldPattern = |
| [ModifiersPattern] TypePattern [TypePattern . ] IdPattern |
| ThrowsPattern = |
| [ ! ] TypePattern , ... |
| TypePattern = |
| IdPattern [ + ] [ [] ... ] |
| | ! TypePattern |
| | TypePattern && TypePattern |
| | TypePattern || TypePattern |
| | ( TypePattern ) |
| IdPattern = |
| Sequence of characters, possibly with special * and .. wildcards |
| ModifiersPattern = |
| [ ! ] JavaModifier ... |
| </pre></div></div><div class="sect1"><a name="semantics-advice"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="semantics-advice"></a>Advice</h2></div></div><p> |
| Each piece of advice is of the form |
| |
| <blockquote class="blockquote"><tt>[ strictfp ] <i><tt>AdviceSpec</tt></i> [ |
| throws <i><tt>TypeList</tt></i> ] : |
| <i><tt>Pointcut</tt></i> { |
| <i><tt>Body</tt></i> } </tt></blockquote> |
| |
| where <i><tt>AdviceSpec</tt></i> is one of |
| </p><div class="itemizedlist"><ul><li><a name="d0e6012"></a><tt>before( <i><tt>Formals</tt></i> ) </tt></li><li><a name="d0e6018"></a><tt>after( <i><tt>Formals</tt></i> ) returning |
| [ ( <i><tt>Formal</tt></i> ) ] </tt></li><li><a name="d0e6027"></a><tt>after( <i><tt>Formals</tt></i> ) throwing [ |
| ( <i><tt>Formal</tt></i> ) ] </tt></li><li><a name="d0e6036"></a><tt>after( <i><tt>Formals</tt></i> ) </tt></li><li><a name="d0e6042"></a><tt><i><tt>Type</tt></i> |
| around( <i><tt>Formals</tt></i> )</tt></li></ul></div><p> |
| and where <i><tt>Formal</tt></i> refers to a |
| variable binding like those used for method parameters, |
| of the form |
| <tt><i><tt>Type</tt></i></tt> |
| <tt><i><tt>Variable-Name</tt></i></tt>, |
| and <i><tt>Formals</tt></i> refers to a comma-delimited |
| list of <i><tt>Formal</tt></i>. |
| </p><p> |
| Advice defines crosscutting behavior. It is defined in terms of |
| pointcuts. The code of a piece of advice runs at every join point |
| picked out by its pointcut. Exactly how the code runs depends on the |
| kind of advice. |
| </p><p> |
| AspectJ supports three kinds of advice. The kind of advice determines how |
| it interacts with the join points it is defined over. Thus AspectJ |
| divides advice into that which runs before its join points, that which |
| runs after its join points, and that which runs in place of (or "around") |
| its join points. |
| </p><p> |
| While before advice is relatively unproblematic, there can be three |
| interpretations of after advice: After the execution of a join point |
| completes normally, after it throws an exception, or after it does either |
| one. AspectJ allows after advice for any of these situations. |
| </p><pre class="programlisting"> |
| aspect A { |
| pointcut publicCall(): call(public Object *(..)); |
| after() returning (Object o): publicCall() { |
| System.out.println("Returned normally with " + o); |
| } |
| after() throwing (Exception e): publicCall() { |
| System.out.println("Threw an exception: " + e); |
| } |
| after(): publicCall(){ |
| System.out.println("Returned or threw an Exception"); |
| } |
| } |
| </pre><p> |
| After returning advice may not care about its returned object, in which |
| case it may be written |
| </p><pre class="programlisting"> |
| after() returning: call(public Object *(..)) { |
| System.out.println("Returned normally"); |
| } |
| </pre><p> |
| If after returning does expose its returned object, then the |
| type of the parameter is considered to be an |
| <tt>instanceof</tt>-like constraint on the advice: it |
| will run only when the return value is of the appropriate type. |
| </p><p> |
| A value is of the appropriate type if it would be assignable to |
| a variable of that type, in the Java sense. That is, a |
| <tt>byte</tt> value is assignable to a |
| <tt>short</tt> parameter but not vice-versa, an |
| <tt>int</tt> is assignable to a |
| <tt>float</tt> parameter, <tt>boolean</tt> |
| values are only assignable to <tt>boolean</tt> |
| parameters, and reference types work by instanceof. |
| </p><p> |
| There are two special cases: If the exposed value is typed to |
| <tt>Object</tt>, then the advice is not constrained by |
| that type: the actual return value is converted to an object |
| type for the body of the advice: <tt>int</tt> values |
| are represented as <tt>java.lang.Integer</tt> objects, |
| etc, and no value (from void methods, for example) is |
| represented as <tt>null</tt>. |
| </p><p> |
| Secondly, the <tt>null</tt> value is assignable to a |
| parameter <tt>T</tt> if the join point |
| <span class="emphasis"><i>could</i></span> return something of type |
| <tt>T</tt>. |
| </p><p> |
| Around advice runs in place of the join point it operates over, rather |
| than before or after it. Because around is allowed to return a value, it |
| must be declared with a return type, like a method. |
| </p><p> |
| Thus, a simple use of around advice is to make a particular method |
| constant: |
| </p><pre class="programlisting"> |
| aspect A { |
| int around(): call(int C.foo()) { |
| return 3; |
| } |
| } |
| </pre><p> |
| Within the body of around advice, though, the computation of the original |
| join point can be executed with the special syntax |
| </p><pre class="programlisting"> |
| proceed( ... ) |
| </pre><p> |
| The proceed form takes as arguments the context exposed by the around's |
| pointcut, and returns whatever the around is declared to return. So the |
| following around advice will double the second argument to |
| <tt>foo</tt> whenever it is called, and then halve its result: |
| </p><pre class="programlisting"> |
| aspect A { |
| int around(int i): call(int C.foo(Object, int)) && args(i) { |
| int newi = proceed(i*2) |
| return newi/2; |
| } |
| } |
| </pre><p> |
| If the return value of around advice is typed to |
| <tt>Object</tt>, then the result of proceed is converted to an |
| object representation, even if it is originally a primitive value. And |
| when the advice returns an Object value, that value is converted back to |
| whatever representation it was originally. So another way to write the |
| doubling and halving advice is: |
| </p><pre class="programlisting"> |
| aspect A { |
| Object around(int i): call(int C.foo(Object, int)) && args(i) { |
| Integer newi = (Integer) proceed(i*2) |
| return new Integer(newi.intValue() / 2); |
| } |
| } |
| </pre><p> |
| Any occurence of <tt>proceed(..)</tt> within the body of |
| around advice is treated as the special proceed form (even if the |
| aspect defines a method named <tt>proceed</tt>) unless a |
| target other than the aspect instance is specified as the recipient of |
| the call. |
| For example, in the following program the first |
| call to proceed will be treated as a method call to |
| the <tt>ICanProceed</tt> instance, whereas the second call to |
| proceed is treated as the special proceed form. |
| </p><pre class="programlisting"> |
| aspect A { |
| Object around(ICanProceed canProceed) : execution(* *(..)) && this(canProceed) { |
| canProceed.proceed(); // a method call |
| return proceed(canProceed); // the special proceed form |
| } |
| |
| private Object proceed(ICanProceed canProceed) { |
| // this method cannot be called from inside the body of around advice in |
| // the aspect |
| } |
| } |
| </pre><p> |
| In all kinds of advice, the parameters of the advice behave exactly like |
| method parameters. In particular, assigning to any parameter affects |
| only the value of the parameter, not the value that it came from. This |
| means that |
| </p><pre class="programlisting"> |
| aspect A { |
| after() returning (int i): call(int C.foo()) { |
| i = i * 2; |
| } |
| } |
| </pre><p> |
| will <span class="emphasis"><i>not</i></span> double the returned value of the advice. |
| Rather, it will double the local parameter. Changing the values of |
| parameters or return values of join points can be done by using around |
| advice. |
| </p><div class="sect2"><a name="advice-modifiers"></a><div class="titlepage"><div><h3 class="title"><a name="advice-modifiers"></a>Advice modifiers</h3></div></div><p> |
| The <tt>strictfp</tt> modifier is the only modifier allowed |
| on advice, and it has the effect of making all floating-point |
| expressions within the advice be FP-strict. |
| </p></div><div class="sect2"><a name="advice-and-checked-exceptions"></a><div class="titlepage"><div><h3 class="title"><a name="advice-and-checked-exceptions"></a>Advice and checked exceptions</h3></div></div><p> |
| An advice declaration must include a <tt>throws</tt> clause |
| listing the checked exceptions the body may throw. This list of |
| checked exceptions must be compatible with each target join point |
| of the advice, or an error is signalled by the compiler. |
| </p><p> |
| For example, in the following declarations: |
| </p><pre class="programlisting"> |
| import java.io.FileNotFoundException; |
| |
| class C { |
| int i; |
| |
| int getI() { return i; } |
| } |
| |
| aspect A { |
| before(): get(int C.i) { |
| throw new FileNotFoundException(); |
| } |
| before() throws FileNotFoundException: get(int C.i) { |
| throw new FileNotFoundException(); |
| } |
| } |
| </pre><p> |
| both pieces of advice are illegal. The first because the body throws |
| an undeclared checked exception, and the second because field get join |
| points cannot throw <tt>FileNotFoundException</tt>s. |
| </p><p> The exceptions that each kind of join point in AspectJ may throw are: |
| </p><div class="variablelist"><dl><dt><a name="d0e6208"></a><span class="term">method call and execution</span></dt><dd> |
| the checked exceptions declared by the target method's |
| <tt>throws</tt> clause. |
| </dd><dt><a name="d0e6216"></a><span class="term">constructor call and execution</span></dt><dd> |
| the checked exceptions declared by the target constructor's |
| <tt>throws</tt> clause. |
| </dd><dt><a name="d0e6224"></a><span class="term">field get and set</span></dt><dd> |
| no checked exceptions can be thrown from these join points. |
| </dd><dt><a name="d0e6229"></a><span class="term">exception handler execution</span></dt><dd> |
| the exceptions that can be thrown by the target exception handler. |
| </dd><dt><a name="d0e6234"></a><span class="term">static initializer execution</span></dt><dd> |
| no checked exceptions can be thrown from these join points. |
| </dd><dt><a name="d0e6239"></a><span class="term">pre-initialization and initialization</span></dt><dd> |
| any exception that is in the throws clause of |
| <span class="emphasis"><i>all</i></span> constructors of the initialized class. |
| </dd><dt><a name="d0e6247"></a><span class="term">advice execution</span></dt><dd> |
| any exception that is in the throws clause of the advice. |
| </dd></dl></div></div><div class="sect2"><a name="advice-precedence"></a><div class="titlepage"><div><h3 class="title"><a name="advice-precedence"></a>Advice precedence</h3></div></div><p> |
| Multiple pieces of advice may apply to the same join point. In such |
| cases, the resolution order of the advice is based on advice |
| precedence. |
| </p><div class="sect3"><a name="d0e6257"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6257"></a>Determining precedence</h4></div></div><p>There are a number of rules that determine whether a particular |
| piece of advice has precedence over another when they advise the same |
| join point. </p><p>If the two pieces of advice are defined in different aspects, |
| then there are three cases: </p><div class="itemizedlist"><ul><li><a name="d0e6265"></a>If aspect A is matched earlier than aspect B in some |
| <tt>declare precedence</tt> form, then all advice in |
| concrete aspect A has precedence over all advice in concrete aspect B |
| when they are on the same join point. </li><li><a name="d0e6270"></a> |
| Otherwise, if aspect A is a subaspect of aspect B, then all advice |
| defined in A has precedence over all advice defined in |
| B. So, unless otherwise specified with |
| <tt>declare precedence</tt>, advice in a subaspect |
| has precedence over advice in a superaspect. |
| </li><li><a name="d0e6275"></a> |
| Otherwise, if two pieces of advice are defined in two different |
| aspects, it is undefined which one has precedence. |
| </li></ul></div><p>If the two pieces of advice are defined in the same aspect, then |
| there are two cases: </p><div class="itemizedlist"><ul><li><a name="d0e6280"></a>If either are <tt>after</tt> advice, then the one that |
| appears later in the aspect has precedence over the one that appears |
| earlier. </li><li><a name="d0e6285"></a>Otherwise, then the one that appears earlier in the aspect |
| has precedence over the one that appears later. |
| </li></ul></div><p>These rules can lead to circularity, such as</p><pre class="programlisting"> |
| aspect A { |
| before(): execution(void main(String[] args)) {} |
| after(): execution(void main(String[] args)) {} |
| before(): execution(void main(String[] args)) {} |
| } |
| </pre><p>such circularities will result in errors signalled by the compiler. </p></div><div class="sect3"><a name="d0e6293"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6293"></a>Effects of precedence</h4></div></div><p>At a particular join point, advice is ordered by precedence.</p><p>A piece of <tt>around</tt> advice controls whether |
| advice of lower precedence will run by calling |
| <tt>proceed</tt>. The call to <tt>proceed</tt> |
| will run the advice with next precedence, or the computation under the |
| join point if there is no further advice. </p><p>A piece of <tt>before</tt> advice can prevent advice of |
| lower precedence from running by throwing an exception. If it returns |
| normally, however, then the advice of the next precedence, or the |
| computation under the join pint if there is no further advice, will run. |
| </p><p>Running <tt>after returning</tt> advice will run the |
| advice of next precedence, or the computation under the join point if |
| there is no further advice. Then, if that computation returned |
| normally, the body of the advice will run. </p><p>Running <tt>after throwing</tt> advice will run the |
| advice of next precedence, or the computation under the join |
| point if there is no further advice. Then, if that computation threw |
| an exception of an appropriate type, the body of the advice will |
| run. </p><p>Running <tt>after</tt> advice will run the advice of |
| next precedence, or the computation under the join point if |
| there is no further advice. Then the body of the advice will |
| run. </p></div></div><div class="sect2"><a name="reflective-access-to-the-join-point"></a><div class="titlepage"><div><h3 class="title"><a name="reflective-access-to-the-join-point"></a>Reflective access to the join point</h3></div></div><p> |
| Three special variables are visible within bodies of advice |
| and within <tt>if()</tt> pointcut expressions: |
| <tt>thisJoinPoint</tt>, |
| <tt>thisJoinPointStaticPart</tt>, and |
| <tt>thisEnclosingJoinPointStaticPart</tt>. Each is bound to |
| an object that encapsulates some of the context of the advice's current |
| or enclosing join point. These variables exist because some pointcuts |
| may pick out very large collections of join points. For example, the |
| pointcut |
| </p><pre class="programlisting"> |
| pointcut publicCall(): call(public * *(..)); |
| </pre><p> |
| picks out calls to many methods. Yet the body of advice over this |
| pointcut may wish to have access to the method name or parameters of a |
| particular join point. |
| </p><p> |
| <tt>thisJoinPoint</tt> is bound to a complete join point |
| object. |
| |
| </p><p> |
| <tt>thisJoinPointStaticPart</tt> is bound to a part of the |
| join point object that includes less information, but for which no |
| memory allocation is required on each execution of the advice. It is |
| equivalent to <tt>thisJoinPoint.getStaticPart()</tt>. |
| </p><p> |
| <tt>thisEnclosingJoinPointStaticPart</tt> is bound to the |
| static part of the join point enclosing the current join point. Only |
| the static part of this enclosing join point is available through this |
| mechanism. |
| </p><p> |
| Standard Java reflection uses objects from the |
| <tt>java.lang.reflect</tt> hierarchy to build up its |
| reflective objects. Similarly, AspectJ join point objects have types |
| in a type hierarchy. The type of objects bound to |
| <tt>thisJoinPoint</tt> is |
| <tt>org.aspectj.lang.JoinPoint</tt>, while |
| <tt>thisStaticJoinPoint</tt> is bound to objects of interface |
| type <tt>org.aspectj.lang.JoinPoint.StaticPart</tt>. |
| </p></div></div><div class="sect1"><a name="semantics-declare"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="semantics-declare"></a>Static crosscutting</h2></div></div><p> |
| Advice declarations change the behavior of classes they crosscut, but do |
| not change their static type structure. For crosscutting concerns that do |
| operate over the static structure of type hierarchies, AspectJ provides |
| inter-type member declarations and other <tt>declare</tt> forms. |
| </p><div class="sect2"><a name="inter-type-member-declarations"></a><div class="titlepage"><div><h3 class="title"><a name="inter-type-member-declarations"></a>Inter-type member declarations</h3></div></div><p> |
| AspectJ allows the declaration of members by aspects that are |
| associated with other types. |
| </p><p> |
| An inter-type method declaration looks like |
| </p><div class="itemizedlist"><ul><li><a name="d0e6401"></a><tt> |
| [ <i><tt>Modifiers</tt></i> ] |
| <i><tt>Type</tt></i> <i><tt>OnType</tt></i> |
| . |
| <i><tt>Id</tt></i>(<i><tt>Formals</tt></i>) |
| [ <i><tt>ThrowsClause</tt></i> ] |
| { <i><tt>Body</tt></i> }</tt></li><li><a name="d0e6425"></a><tt>abstract |
| [ <i><tt>Modifiers</tt></i> ] |
| <i><tt>Type</tt></i> <i><tt>OnType</tt></i> |
| . <i><tt>Id</tt></i>(<i><tt>Formals</tt></i>) |
| [ <i><tt>ThrowsClause</tt></i> ] |
| ; |
| </tt></li></ul></div><p> |
| The effect of such a declaration is to make <i><tt>OnType</tt></i> |
| support the new method. Even if <i><tt>OnType</tt></i> is |
| an interface. Even if the method is neither public nor abstract. So the |
| following is legal AspectJ code: |
| </p><pre class="programlisting"> |
| interface Iface {} |
| |
| aspect A { |
| private void Iface.m() { |
| System.err.println("I'm a private method on an interface"); |
| } |
| void worksOnI(Iface iface) { |
| // calling a private method on an interface |
| iface.m(); |
| } |
| } |
| </pre><p> |
| An inter-type constructor declaration looks like |
| </p><div class="itemizedlist"><ul><li><a name="d0e6459"></a><tt> |
| [ <i><tt>Modifiers</tt></i> ] |
| <i><tt>OnType</tt></i> . new ( |
| <i><tt>Formals</tt></i> ) |
| [ <i><tt>ThrowsClause</tt></i> ] |
| { <i><tt>Body</tt></i> }</tt></li></ul></div><p> |
| The effect of such a declaration is to make |
| <i><tt>OnType</tt></i> support the new constructor. It is |
| an error for <i><tt>OnType</tt></i> to be an interface. |
| </p><p> |
| Inter-type declared constructors cannot be used to assign a |
| value to a final variable declared in <i><tt>OnType</tt></i>. |
| This limitation significantly increases the ability to both understand |
| and compile the <i><tt>OnType</tt></i> class and the |
| declaring aspect separately. |
| </p><p> |
| Note that in the Java language, classes that define no constructors |
| have an implicit no-argument constructor that just calls |
| <tt>super()</tt>. This means that attempting to declare |
| a no-argument inter-type constructor on such a class may result in |
| a conflict, even though it <span class="emphasis"><i>looks</i></span> like no |
| constructor is defined. |
| </p><p> |
| An inter-type field declaration looks like one of |
| </p><div class="itemizedlist"><ul><li><a name="d0e6504"></a><tt> |
| [ <i><tt>Modifiers</tt></i> ] |
| <i><tt>Type</tt></i> |
| <i><tt>OnType</tt></i> . <i><tt>Id</tt></i> |
| = <i><tt>Expression</tt></i>;</tt></li><li><a name="d0e6522"></a><tt> |
| [ <i><tt>Modifiers</tt></i> ] |
| <i><tt>Type</tt></i> |
| <i><tt>OnType</tt></i> . <i><tt>Id</tt></i>;</tt></li></ul></div><p> |
| The effect of such a declaration is to make |
| <i><tt>OnType</tt></i> support the new field. Even if |
| <i><tt>OnType</tt></i> is an interface. Even if the field is |
| neither public, nor static, nor final. |
| </p><p> |
| The initializer, if any, of an inter-type field declaration runs |
| before the class-local initializers defined in its target class. |
| </p></div><p> |
| Any occurrence of the identifier <tt>this</tt> in the body of |
| an inter-type constructor or method declaration, or in the initializer |
| of an inter-type field declaration, refers to the |
| <i><tt>OnType</tt></i> object rather than to the aspect |
| type; it is an error to access <tt>this</tt> in such a |
| position from a <tt>static</tt> inter-type member |
| declaration. |
| </p><div class="sect2"><a name="access-modifiers"></a><div class="titlepage"><div><h3 class="title"><a name="access-modifiers"></a>Access modifiers</h3></div></div><p> |
| Inter-type member declarations may be public or private, or have |
| default (package-protected) visibility. AspectJ does not provide |
| protected inter-type members. |
| </p><p> |
| The access modifier applies in relation to the aspect, not in relation |
| to the target type. So a private inter-type member is visible only from |
| code that is defined within the declaring aspect. A default-visibility |
| inter-type member is visible only from code that is defined within the |
| declaring aspect's package. |
| </p><p> |
| Note that a declaring a private inter-type method (which AspectJ |
| supports) is very different from inserting a private method declaration |
| into another class. The former allows access only from the declaring |
| aspect, while the latter would allow access only from the target type. |
| Java serialization, for example, uses the presense of a private method |
| <tt>void writeObject(ObjectOutputStream)</tt> for the |
| implementation of <tt>java.io.Serializable</tt>. A private |
| inter-type declaration of that method would not fulfill this |
| requirement, since it would be private to the aspect, not private to |
| the target type. |
| </p><p> |
| The access modifier of abstract inter-type methods has |
| one constraint: It is illegal to declare an abstract |
| non-public inter-type method on a public interface. This |
| is illegal because it would say that a public interface |
| has a constraint that only non-public implementors must |
| fulfill. This would not be compatible with Java's type |
| system. |
| </p></div><div class="sect2"><a name="conflicts"></a><div class="titlepage"><div><h3 class="title"><a name="conflicts"></a>Conflicts</h3></div></div><p> |
| Inter-type declarations raise the possibility of conflicts among |
| locally declared members and inter-type members. For example, assuming |
| <tt>otherPackage</tt> is not the package containing the |
| aspect <tt>A</tt>, the code |
| </p><pre class="programlisting"> |
| aspect A { |
| private Registry otherPackage.onType.r; |
| public void otherPackage.onType.register(Registry r) { |
| r.register(this); |
| this.r = r; |
| } |
| } |
| </pre><p> |
| declares that <tt>onType</tt> in <tt>otherPackage</tt> has a field |
| <tt>r</tt>. This field, however, is only accessible from the |
| code inside of aspect <tt>A</tt>. The aspect also declares |
| that <tt>onType</tt> has a method |
| "<tt>register</tt>", but makes this method accessible from |
| everywhere. |
| </p><p> |
| If <tt>onType</tt> already defines a |
| private or package-protected field "<tt>r</tt>", there is no |
| conflict: The aspect cannot see such a field, and no code in |
| <tt>otherPackage</tt> can see the inter-type |
| "<tt>r</tt>". |
| </p><p> |
| If <tt>onType</tt> defines a public field |
| "<tt>r</tt>", there is a conflict: The expression |
| </p><pre class="programlisting"> |
| this.r = r |
| </pre><p> |
| is an error, since it is ambiguous whether the private inter-type |
| "<tt>r</tt>" or the public locally-defined |
| "<tt>r</tt>" should be used. |
| </p><p> |
| If <tt>onType</tt> defines a method |
| "<tt>register(Registry)</tt>" there is a conflict, since it |
| would be ambiguous to any code that could see such a defined method |
| which "<tt>register(Registry)</tt>" method was applicable. |
| </p><p> |
| Conflicts are resolved as much as possible as per Java's conflict |
| resolution rules: |
| </p><div class="itemizedlist"><ul><li><a name="d0e6657"></a>A subclass can inherit multiple <span class="emphasis"><i>fields</i></span> from its superclasses, |
| all with the same name and type. However, it is an error to have an ambiguous |
| <span class="emphasis"><i>reference</i></span> to a field.</li><li><a name="d0e6665"></a>A subclass can only inherit multiple |
| <span class="emphasis"><i>methods</i></span> with the same name and argument types from |
| its superclasses if only zero or one of them is concrete (i.e., all but |
| one is abstract, or all are abstract). |
| </li></ul></div><p> |
| Given a potential conflict between inter-type member declarations in |
| different aspects, if one aspect has precedence over the other its |
| declaration will take effect without any conflict notice from compiler. |
| This is true both when the precedence is declared explicitly with |
| <tt>declare precedence</tt> as well as when when sub-aspects |
| implicitly have precedence over their super-aspect. |
| </p></div><div class="sect2"><a name="extension-and-implementation"></a><div class="titlepage"><div><h3 class="title"><a name="extension-and-implementation"></a>Extension and Implementation</h3></div></div><p> |
| An aspect may change the inheritance hierarchy of a system by changing |
| the superclass of a type or adding a superinterface onto a type, with |
| the <tt>declare parents</tt> form. |
| </p><div class="itemizedlist"><ul><li><a name="d0e6684"></a><tt>declare parents: <i><tt>TypePattern</tt></i> extends <i><tt>Type</tt></i>;</tt></li><li><a name="d0e6693"></a><tt>declare parents: <i><tt>TypePattern</tt></i> implements <i><tt>TypeList</tt></i>;</tt></li></ul></div><p> |
| For example, if an aspect wished to make a particular class runnable, |
| it might define appropriate inter-type <tt>void |
| run()</tt> method, but it should also declare that the class |
| fulfills the <tt>Runnable</tt> interface. In order to |
| implement the methods in the <tt>Runnable</tt> interface, the |
| inter-type <tt>run()</tt> method must be public: |
| </p><pre class="programlisting"> |
| aspect A { |
| declare parents: SomeClass implements Runnable; |
| public void SomeClass.run() { ... } |
| } |
| </pre></div><div class="sect2"><a name="interfaces-with-members"></a><div class="titlepage"><div><h3 class="title"><a name="interfaces-with-members"></a>Interfaces with members</h3></div></div><p> |
| Through the use of inter-type members, interfaces may now carry |
| (non-public-static-final) fields and (non-public-abstract) methods that |
| classes can inherit. Conflicts may occur from ambiguously inheriting |
| members from a superclass and multiple superinterfaces. |
| </p><p> |
| Because interfaces may carry non-static initializers, each interface |
| behaves as if it has a zero-argument constructor containing its |
| initializers. The order of super-interface instantiation is |
| observable. We fix this order with the following properties: A |
| supertype is initialized before a subtype, initialized code runs only |
| once, and the initializers for a type's superclass are run before the |
| initializers for its superinterfaces. Consider the following hierarchy |
| where {<tt>Object</tt>, <tt>C</tt>, |
| <tt>D</tt>, <tt>E</tt>} are classes, |
| {<tt>M</tt>, <tt>N</tt>, <tt>O</tt>, |
| <tt>P</tt>, <tt>Q</tt>} are interfaces. |
| </p><pre class="programlisting"> |
| Object M O |
| \ / \ / |
| C N Q |
| \ / / |
| D P |
| \ / |
| E |
| </pre><p> |
| when a new <tt>E</tt> is instantiated, the initializers run in this order: |
| </p><pre class="programlisting"> |
| Object M C O N D Q P E |
| </pre></div><div class="sect2"><a name="warnings-and-errors"></a><div class="titlepage"><div><h3 class="title"><a name="warnings-and-errors"></a>Warnings and Errors</h3></div></div><p>An aspect may specify that a particular join point should never be |
| reached. </p><div class="itemizedlist"><ul><li><a name="d0e6768"></a><tt>declare error: <i><tt>Pointcut</tt></i>: <i><tt>String</tt></i>;</tt></li><li><a name="d0e6777"></a><tt>declare warning: <i><tt>Pointcut</tt></i>: <i><tt>String</tt></i>;</tt></li></ul></div><p>If the compiler determines that a join point in |
| <i><tt>Pointcut</tt></i> could possibly be reached, then it |
| will signal either an error or warning, as declared, using the |
| <i><tt>String</tt></i> for its message. </p></div><div class="sect2"><a name="softened-exceptions"></a><div class="titlepage"><div><h3 class="title"><a name="softened-exceptions"></a>Softened exceptions</h3></div></div><p>An aspect may specify that a particular kind of exception, if |
| thrown at a join point, should bypass Java's usual static exception |
| checking system and instead be thrown as a |
| <tt>org.aspectj.lang.SoftException</tt>, which is subtype of |
| <tt>RuntimeException</tt> and thus does not need to be |
| declared. </p><div class="itemizedlist"><ul><li><a name="d0e6806"></a><tt>declare soft: <i><tt>Type</tt></i>: <i><tt>Pointcut</tt></i>;</tt></li></ul></div><p>For example, the aspect</p><pre class="programlisting"> |
| aspect A { |
| declare soft: Exception: execution(void main(String[] args)); |
| } |
| </pre><p>Would, at the execution join point, catch any |
| <tt>Exception</tt> and rethrow a |
| <tt>org.aspectj.lang.SoftException</tt> containing |
| original exception. </p><p>This is similar to what the following advice would do</p><pre class="programlisting"> |
| aspect A { |
| void around() execution(void main(String[] args)) { |
| try { proceed(); } |
| catch (Exception e) { |
| throw new org.aspectj.lang.SoftException(e); |
| } |
| } |
| } |
| </pre><p>except, in addition to wrapping the exception, it also affects |
| Java's static exception checking mechanism. </p><p> Like advice, the declare soft form has no effect in an |
| abstract aspect that is not extended by a concreate aspect. So |
| the following code will not compile unless it is compiled with an |
| extending concrete aspect:</p><pre class="programlisting"> |
| abstract aspect A { |
| abstract pointcut softeningPC(); |
| |
| before() : softeningPC() { |
| Class.forName("FooClass"); // error: uncaught ClassNotFoundException |
| } |
| |
| declare soft : ClassNotFoundException : call(* Class.*(..)); |
| } |
| </pre></div><div class="sect2"><a name="advice-precedence"></a><div class="titlepage"><div><h3 class="title"><a name="advice-precedence"></a>Advice Precedence</h3></div></div><p> |
| An aspect may declare a precedence relationship between concrete |
| aspects with the <tt>declare precedence</tt> form: |
| </p><div class="itemizedlist"><ul><li><a name="d0e6846"></a><tt>declare precedence : |
| <i><tt>TypePatternList</tt></i> ; </tt></li></ul></div><p>This signifies that if any join point has advice from two |
| concrete aspects matched by some pattern in |
| <i><tt>TypePatternList</tt></i>, then the precedence of |
| the advice will be the order of in the list. </p><p>In <i><tt>TypePatternList</tt></i>, the wildcard "*" can |
| appear at most once, and it means "any type not matched by any other |
| pattern in the list". </p><p>For example, the constraints that (1) aspects that have |
| Security as part of their name should have precedence over all other |
| aspects, and (2) the Logging aspect (and any aspect that extends it) |
| should have precedence over all non-security aspects, can be |
| expressed by:</p><pre class="programlisting"> |
| declare precedence: *..*Security*, Logging+, *; |
| </pre><p> |
| For another example, the CountEntry aspect might want to count the |
| entry to methods in the current package accepting a Type object as |
| its first argument. However, it should count all entries, even |
| those that the aspect DisallowNulls causes to throw exceptions. |
| This can be accomplished by stating that CountEntry has precedence |
| over DisallowNulls. This declaration could be in either aspect, or |
| in another, ordering aspect: |
| </p><pre class="programlisting"> |
| aspect Ordering { |
| declare precedence: CountEntry, DisallowNulls; |
| } |
| aspect DisallowNulls { |
| pointcut allTypeMethods(Type obj): call(* *(..)) && args(obj, ..); |
| before(Type obj): allTypeMethods(obj) { |
| if (obj == null) throw new RuntimeException(); |
| } |
| } |
| aspect CountEntry { |
| pointcut allTypeMethods(Type obj): call(* *(..)) && args(obj, ..); |
| static int count = 0; |
| before(): allTypeMethods(Type) { |
| count++; |
| } |
| } |
| </pre><div class="sect3"><a name="d0e6870"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6870"></a>Various cycles</h4></div></div><p> |
| It is an error for any aspect to be matched by more than one |
| TypePattern in a single decare precedence, so: |
| </p><pre class="programlisting"> |
| declare precedence: A, B, A ; // error |
| </pre><p> |
| However, multiple declare precedence forms may legally have this |
| kind of circularity. For example, each of these declare |
| precedence is perfectly legal: |
| </p><pre class="programlisting"> |
| declare precedence: B, A; |
| declare precedence: A, B; |
| </pre><p> |
| And a system in which both constraints are active may also be |
| legal, so long as advice from A and B don't share a join |
| point. So this is an idiom that can be used to enforce that A and |
| B are strongly independent. |
| </p></div><div class="sect3"><a name="d0e6883"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6883"></a>Applies to concrete aspects</h4></div></div><p> |
| Consider the following library aspects: |
| </p><pre class="programlisting"> |
| abstract aspect Logging { |
| abstract pointcut logged(); |
| |
| before(): logged() { |
| System.err.println("thisJoinPoint: " + thisJoinPoint); |
| } |
| } |
| |
| abstract aspect MyProfiling { |
| abstract pointcut profiled(); |
| |
| Object around(): profiled() { |
| long beforeTime = System.currentTimeMillis(); |
| try { |
| return proceed(); |
| } finally { |
| long afterTime = System.currentTimeMillis(); |
| addToProfile(thisJoinPointStaticPart, |
| afterTime - beforeTime); |
| } |
| } |
| abstract void addToProfile( |
| org.aspectj.JoinPoint.StaticPart jp, |
| long elapsed); |
| } |
| </pre><p> |
| In order to use either aspect, they must be extended with |
| concrete aspects, say, MyLogging and MyProfiling. Because advice |
| only applies from concrete aspects, the declare precedence form |
| only matters when declaring precedence with concrete aspects. So |
| </p><pre class="programlisting"> |
| declare precedence: Logging, Profiling; |
| </pre><p> |
| has no effect, but both |
| </p><pre class="programlisting"> |
| declare precedence: MyLogging, MyProfiling; |
| declare precedence: Logging+, Profiling+; |
| </pre><p> |
| are meaningful. |
| </p></div></div><div class="sect2"><a name="statically-determinable-pointcuts"></a><div class="titlepage"><div><h3 class="title"><a name="statically-determinable-pointcuts"></a>Statically determinable pointcuts</h3></div></div><p>Pointcuts that appear inside of <tt>declare</tt> forms |
| have certain restrictions. Like other pointcuts, these pick out join |
| points, but they do so in a way that is statically determinable. </p><p>Consequently, such pointcuts may not include, directly or |
| indirectly (through user-defined pointcut declarations) pointcuts that |
| discriminate based on dynamic (runtime) context. Therefore, such |
| pointcuts may not be defined in terms of</p><div class="itemizedlist"><ul><li><a name="d0e6911"></a>cflow</li><li><a name="d0e6913"></a>cflowbelow</li><li><a name="d0e6915"></a>this</li><li><a name="d0e6917"></a>target</li><li><a name="d0e6919"></a>args</li><li><a name="d0e6921"></a>if</li></ul></div><p> all of which can discriminate on runtime information. </p></div></div><div class="sect1"><a name="semantics-aspects"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="semantics-aspects"></a>Aspects</h2></div></div><p> |
| An aspect is a crosscutting type defined by the <tt>aspect</tt> |
| declaration. |
| </p><div class="sect2"><a name="aspect-declaration"></a><div class="titlepage"><div><h3 class="title"><a name="aspect-declaration"></a>Aspect Declaration</h3></div></div><p> |
| The <tt>aspect</tt> declaration is similar to the |
| <tt>class</tt> declaration in that it defines a type and an |
| implementation for that type. It differs in a number of |
| ways: |
| </p><div class="sect3"><a name="d0e6944"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6944"></a>Aspect implementation can cut across other types</h4></div></div><p> In addition to normal Java class declarations such as |
| methods and fields, aspect declarations can include AspectJ |
| declarations such as advice, pointcuts, and inter-type |
| declarations. Thus, aspects contain implementation |
| declarations that can can cut across other types (including those defined by |
| other aspect declarations). |
| </p></div><div class="sect3"><a name="d0e6949"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6949"></a>Aspects are not directly instantiated</h4></div></div><p> Aspects are not directly instantiated with a new |
| expression, with cloning, or with serialization. Aspects may |
| have one constructor definition, but if so it must be of a |
| constructor taking no arguments and throwing no checked |
| exceptions. |
| </p></div><div class="sect3"><a name="d0e6954"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6954"></a>Nested aspects must be <tt>static</tt></h4></div></div><p> |
| Aspects may be defined either at the package level, or as a static nested |
| aspect -- that is, a static member of a class, interface, or aspect. If it |
| is not at the package level, the aspect <span class="emphasis"><i>must</i></span> be |
| defined with the static keyword. Local and anonymous aspects are not |
| allowed. |
| </p></div></div><div class="sect2"><a name="aspect-extension"></a><div class="titlepage"><div><h3 class="title"><a name="aspect-extension"></a>Aspect Extension</h3></div></div><p> |
| To support abstraction and composition of crosscutting concerns, |
| aspects can be extended in much the same way that classes can. Aspect |
| extension adds some new rules, though. |
| </p><div class="sect3"><a name="d0e6969"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6969"></a>Aspects may extend classes and implement interfaces</h4></div></div><p> |
| An aspect, abstract or concrete, may extend a class and may implement |
| a set of interfaces. Extending a class does not provide the ability |
| to instantiate the aspect with a new expression: The aspect may still |
| only define a null constructor. |
| </p></div><div class="sect3"><a name="d0e6974"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6974"></a>Classes may not extend aspects</h4></div></div><p> |
| It is an error for a class to extend or implement an aspect. |
| </p></div><div class="sect3"><a name="d0e6979"></a><div class="titlepage"><div><h4 class="title"><a name="d0e6979"></a>Aspects extending aspects |
| </h4></div></div><p> |
| Aspects may extend other aspects, in which case not only are fields |
| and methods inherited but so are pointcuts. However, aspects may only |
| extend abstract aspects. It is an error for a concrete aspect to |
| extend another concrete aspect. |
| </p></div></div><div class="sect2"><a name="aspect-instantiation"></a><div class="titlepage"><div><h3 class="title"><a name="aspect-instantiation"></a>Aspect instantiation</h3></div></div><p> |
| Unlike class expressions, aspects are not instantiated with |
| <tt>new</tt> expressions. Rather, aspect instances are |
| automatically created to cut across programs. A program |
| can get a reference to an aspect instance using the static |
| method <tt>aspectOf(..)</tt>. |
| </p><p> |
| Because advice only runs in the context of an aspect instance, aspect |
| instantiation indirectly controls when advice runs. |
| </p><p> |
| The criteria used to determine how an aspect is instantiated |
| is inherited from its parent aspect. If the aspect has no parent |
| aspect, then by default the aspect is a singleton aspect. |
| How an aspect is instantiated controls the form of the |
| <tt>aspectOf(..)</tt> method defined on the |
| concrete aspect class. |
| </p><div class="sect3"><a name="d0e7002"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7002"></a>Singleton Aspects</h4></div></div><div class="itemizedlist"><ul><li><a name="d0e7006"></a><tt>aspect <i><tt>Id</tt></i> { ... }</tt></li><li><a name="d0e7012"></a><tt>aspect <i><tt>Id</tt></i> issingleton() { ... }</tt></li></ul></div><p> |
| By default (or by using the modifier <tt>issingleton()</tt>) |
| an aspect has exactly one instance that cuts across the entire |
| program. That instance is available at any time during program |
| execution from the static method <tt>aspectOf()</tt> |
| automatically defined on all concrete aspects |
| -- so, in the above examples, <tt>A.aspectOf()</tt> will |
| return A's instance. This aspect instance is created as the aspect's |
| classfile is loaded. |
| </p><p> |
| Because the an instance of the aspect exists at all join points in |
| the running of a program (once its class is loaded), its advice will |
| have a chance to run at all such join points. |
| </p><p> |
| (In actuality, one instance of the aspect A is made for each version |
| of the aspect A, so there will be one instantiation for each time A |
| is loaded by a different classloader.) |
| </p></div><div class="sect3"><a name="d0e7033"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7033"></a>Per-object aspects</h4></div></div><div class="itemizedlist"><ul><li><a name="d0e7037"></a><tt>aspect <i><tt>Id</tt></i> perthis(<i><tt>Pointcut</tt></i>) { ... }</tt></li><li><a name="d0e7046"></a><tt>aspect <i><tt>Id</tt></i> pertarget(<i><tt>Pointcut</tt></i>) { ... }</tt></li></ul></div><p> |
| If an aspect A is defined |
| <tt>perthis(<i><tt>Pointcut</tt></i>)</tt>, then |
| one object of type A is created for every object that is the |
| executing object (i.e., "this") at any of the join points picked out |
| by <i><tt>Pointcut</tt></i>. |
| The advice defined in A will run only at a join point where the |
| currently executing object has been associated with an instance of |
| A. |
| </p><p> Similarly, if an aspect A is defined |
| <tt>pertarget(<i><tt>Pointcut</tt></i>)</tt>, |
| then one object of type A is created for every object that is the |
| target object of the join points picked out by |
| <i><tt>Pointcut</tt></i>. |
| The advice defined in A will run only at a join point where the |
| target object has been associated with an instance of |
| A. |
| </p><p> |
| In either case, the static method call |
| <tt>A.aspectOf(Object)</tt> can be used to get the aspect |
| instance (of type A) registered with the object. Each aspect |
| instance is created as early as possible, but not before reaching a |
| join point picked out by <i><tt>Pointcut</tt></i> where |
| there is no associated aspect of type A. |
| </p><p> Both <tt>perthis</tt> and <tt>pertarget</tt> |
| aspects may be affected by code the AspectJ compiler controls, as |
| discussed in the <a href="#implementation">Implementation Notes</a> appendix. </p></div><div class="sect3"><a name="d0e7095"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7095"></a>Per-control-flow aspects</h4></div></div><div class="itemizedlist"><ul><li><a name="d0e7099"></a><tt>aspect <i><tt>Id</tt></i> percflow(<i><tt>Pointcut</tt></i>) { ... }</tt></li><li><a name="d0e7108"></a><tt>aspect <i><tt>Id</tt></i> percflowbelow(<i><tt>Pointcut</tt></i>) { ... }</tt></li></ul></div><p> |
| If an aspect A is defined |
| <tt>percflow(<i><tt>Pointcut</tt></i>)</tt> or |
| <tt>percflowbelow(<i><tt>Pointcut</tt></i>)</tt>, |
| then one object of type A is created for each flow of control of the |
| join points picked out by <i><tt>Pointcut</tt></i>, either |
| as the flow of control is entered, or below the flow of control, |
| respectively. The advice defined in A may run at any join point in |
| or under that control flow. During each such flow of control, the |
| static method <tt>A.aspectOf()</tt> will return an object |
| of type |
| A. An instance of the aspect is created upon entry into each such |
| control flow. |
| </p></div><div class="sect3"><a name="d0e7137"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7137"></a>Aspect instantiation and advice</h4></div></div><p> |
| All advice runs in the context of an aspect instance, |
| but it is possible to write a piece of advice with a pointcut |
| that picks out a join point that must occur before asopect |
| instantiation. For example: |
| </p><pre class="programlisting"> |
| public class Client |
| { |
| public static void main(String[] args) { |
| Client c = new Client(); |
| } |
| } |
| |
| aspect Watchcall { |
| pointcut myConstructor(): execution(new(..)); |
| |
| before(): myConstructor() { |
| System.err.println("Entering Constructor"); |
| } |
| } |
| </pre><p> |
| The before advice should run before the execution of all |
| constructors in the system. It must run in the context of an |
| instance of the Watchcall aspect. The only way to get such an |
| instance is to have Watchcall's default constructor execute. But |
| before that executes, we need to run the before advice... |
| </p><p> |
| There is no general way to detect these kinds of circularities at |
| compile time. If advice runs before its aspect is instantiated, |
| AspectJ will throw a <a href="../api/org/aspectj/lang/NoAspectBoundException.html" target="_top"> |
| <tt>org.aspectj.lang.NoAspectBoundException</tt></a>. |
| </p></div></div><div class="sect2"><a name="aspect-privilege"></a><div class="titlepage"><div><h3 class="title"><a name="aspect-privilege"></a>Aspect privilege</h3></div></div><div class="itemizedlist"><ul><li><a name="d0e7157"></a><tt>privileged aspect <i><tt>Id</tt></i> { ... }</tt></li></ul></div><p> |
| Code written in aspects is subject to the same access control rules as |
| Java code when referring to members of classes or aspects. So, for |
| example, code written in an aspect may not refer to members with |
| default (package-protected) visibility unless the aspect is defined in |
| the same package. |
| </p><p> |
| While these restrictions are suitable for many aspects, there may be |
| some aspects in which advice or inter-type members needs to access private |
| or protected resources of other types. To allow this, aspects may be |
| declared <tt>privileged</tt>. Code in priviliged aspects has |
| access to all members, even private ones. |
| </p><pre class="programlisting"> |
| class C { |
| private int i = 0; |
| void incI(int x) { i = i+x; } |
| } |
| privileged aspect A { |
| static final int MAX = 1000; |
| before(int x, C c): call(void C.incI(int)) && target(c) && args(x) { |
| if (c.i+x > MAX) throw new RuntimeException(); |
| } |
| } |
| </pre><p> |
| In this case, if A had not been declared privileged, the field reference |
| c.i would have resulted in an error signaled by the compiler. |
| </p><p> |
| If a privileged aspect can access multiple versions of a particular |
| member, then those that it could see if it were not privileged take |
| precedence. For example, in the code |
| </p><pre class="programlisting"> |
| class C { |
| private int i = 0; |
| void foo() { } |
| } |
| privileged aspect A { |
| private int C.i = 999; |
| before(C c): call(void C.foo()) target(c) { |
| System.out.println(c.i); |
| } |
| } |
| </pre><p> |
| A's private inter-type field C.i, initially bound to 999, will be |
| referenced in the body of the advice in preference to C's privately |
| declared field, since the A would have access to its own inter-type |
| fields even if it were not privileged. |
| </p><p> |
| Note that a privileged aspect can access private inter-type |
| declarations made by other aspects, since they are simply |
| considered private members of that other aspect. |
| </p></div></div></div><div class="appendix"><div class="titlepage"><div><h2 class="title"><a name="implementation"></a>Appendix C. Implementation Notes</h2></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#d0e7185">Compiler Notes</a></dt><dt><a href="#d0e7259">Bytecode Notes</a></dt><dd><dl><dt><a href="#the-class-expression-and-string">The .class expression and String +</a></dt><dt><a href="#the-handler-join-point">The Handler join point</a></dt><dt><a href="#initializers-and-inter-type-constructors">Initializers and Inter-type Constructors</a></dt></dl></dd><dt><a href="#d0e7365">Summary of implementation requirements</a></dt></dl></div><div class="sect1"><a name="d0e7185"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="d0e7185"></a>Compiler Notes</h2></div></div><p> |
| The initial implementations of AspectJ have all been |
| compiler-based implementations. Certain elements of AspectJ's |
| semantics are difficult to implement without making modifications |
| to the virtual machine, which a compiler-based implementation |
| cannot do. One way to deal with this problem would be to specify |
| only the behavior that is easiest to implement. We have chosen a |
| somewhat different approach, which is to specify an ideal language |
| semantics, as well as a clearly defined way in which |
| implementations are allowed to deviate from that semantics. This |
| makes it possible to develop conforming AspectJ implementations |
| today, while still making it clear what later, and presumably |
| better, implementations should do tomorrow. |
| </p><p> |
| According to the AspectJ language semantics, the declaration |
| </p><pre class="programlisting"> |
| before(): get(int Point.x) { System.out.println("got x"); } |
| </pre><p> |
| should advise all accesses of a field of type int and name x from |
| instances of type (or subtype of) Point. It should do this |
| regardless of whether all the source code performing the access |
| was available at the time the aspect containing this advice was |
| compiled, whether changes were made later, etc. |
| </p><p> |
| But AspectJ implementations are permitted to deviate from this in |
| a well-defined way -- they are permitted to advise only accesses |
| in <span class="emphasis"><i>code the implementation controls</i></span>. Each |
| implementation is free within certain bounds to provide its own |
| definition of what it means to control code. |
| </p><p> |
| In the current AspectJ compiler, ajc, control of the code means |
| having bytecode for any aspects and all the code they should |
| affect available during the compile. This means that if some class |
| Client contains code with the expression <tt>new |
| Point().x</tt> (which results in a field get join point at |
| runtime), the current AspectJ compiler will fail to advise that |
| access unless Client.java or Client.class is compiled as well. It |
| also means that join points associated with code in native methods |
| (including their execution join points) cannot be advised. |
| </p><p> |
| Different join points have different requirements. Method and |
| constructor call join points can be advised only if ajc controls |
| the bytecode for the caller. Field reference or assignment join |
| points can be advised only if ajc controls the bytecode for the |
| "caller", the code actually making the reference or assignment. |
| Initialization join points can be advised only if ajc controls the |
| bytecode of the type being initialized, and execution join points |
| can be advised only if ajc controls the bytecode for the method or |
| constructor body in question. |
| The end of an exception handler is underdetermined in bytecode, |
| so ajc will not implement after or around advice on handler join |
| points. |
| Similarly, ajc cannot implement around advice on initialization |
| or preinitialization join points. |
| In cases where ajc cannot implement advice, it will emit a |
| compile-time error noting this as a compiler limitation. |
| </p><p> |
| Aspects that are defined <tt>perthis</tt> or |
| <tt>pertarget</tt> also have restrictions based on |
| control of the code. In particular, at a join point where the |
| bytecode for the currently executing object is not available, an |
| aspect defined <tt>perthis</tt> of that join point will |
| not be associated. So aspects defined |
| <tt>perthis(Object)</tt> will not create aspect |
| instances for every object unless <tt>Object</tt>is part |
| of the compile. Similar restrictions apply to |
| <tt>pertarget</tt> aspects. |
| </p><p> |
| Inter-type declarations such as <tt>declare parents</tt> |
| also have restrictions based on control of the code. If the |
| bytecode for the target of an inter-type declaration is not |
| available, then the inter-type declaration is not made on that |
| target. So, <tt>declare parents : String implements |
| MyInterface</tt> will not work for |
| <tt>java.lang.String</tt> unless |
| <tt>java.lang.String</tt> is part of the compile. |
| </p><p> |
| When declaring members on interfaces, the implementation must |
| control both the interface and the top-level implementors of |
| that interface (the classes that implement the interface but |
| do not have a superclass that implements the interface). |
| You may weave these separately, but be aware that you will get |
| runtime exceptions if you run the affected top-level classes |
| without the interface as produced by the same ajc implementation. |
| Any intertype declaration of an abstract method on an interface |
| must be specified as public, you will get a compile time error |
| message indicating this is a compiler limitation if you do not |
| specify public. A non-abstract method declared on an interface |
| can use any access modifier except protected. Note that this is |
| different to normal Java rules where all members declared in |
| an interface are implicitly public. |
| Finally, note that one cannot define static fields or methods |
| on interfaces. |
| </p><p> |
| When declaring methods on target types, only methods declared |
| public are recognizable in the bytecode, so methods must be |
| declared public to be overridden in any subtype or to be called |
| from code in a later compile using the target type as a library. |
| </p><p> |
| Other AspectJ implementations, indeed, future versions of ajc, may |
| define <span class="emphasis"><i>code the implementation controls</i></span> more |
| liberally or restrictively, so long as they comport with the Java |
| language. For example, the <tt>call</tt> pointcut does |
| not pick out reflective calls to a method implemented in |
| <tt>java.lang.reflect.Method.invoke(Object, Object[])</tt>. |
| Some suggest that the call "happens" and the call pointcut should |
| pick it out, but the AspectJ language shouldn't anticipate what happens |
| in code outside the control of the implementation, even when it |
| is a a well-defined API in a Java standard library. |
| </p><p> |
| The important thing to remember is that core concepts of AspectJ, |
| such as the join point, are unchanged, regardless of which |
| implementation is used. During your development, you will have to |
| be aware of the limitations of the ajc compiler you're using, but |
| these limitations should not drive the design of your aspects. |
| </p></div><div class="sect1"><a name="d0e7259"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="d0e7259"></a>Bytecode Notes</h2></div></div><div class="sect2"><a name="the-class-expression-and-string"></a><div class="titlepage"><div><h3 class="title"><a name="the-class-expression-and-string"></a>The .class expression and String +</h3></div></div><p> The java language form <tt>Foo.class</tt> is |
| implemented in bytecode with a call to |
| <tt>Class.forName</tt> guarded by an exception |
| handler catching a <tt>ClassNotFoundException</tt>. |
| </p><p> The java language + operator, when applied to String |
| arguments, is implemented in bytecode by calls to |
| <tt>StringBuffer.append</tt>. |
| </p><p> In both of these cases, the current AspectJ compiler |
| operates on the bytecode implementation of these language |
| features; in short, it operates on what is really happening rather |
| than what was written in source code. This means that there may |
| be call join points to <tt>Class.forName</tt> or |
| <tt>StringBuffer.append</tt> from programs that do not, |
| at first glance, appear to contain such calls: |
| </p><pre class="programlisting"> |
| class Test { |
| void main(String[] args) { |
| System.out.println(Test.class); // calls Class.forName |
| System.out.println(args[0] + args[1]); // calls StringBuffer.append |
| } |
| } |
| </pre><p>In short, the join point model of the current AspectJ |
| compiler considers these as valid join points. |
| </p></div><div class="sect2"><a name="the-handler-join-point"></a><div class="titlepage"><div><h3 class="title"><a name="the-handler-join-point"></a>The Handler join point</h3></div></div><p>The end of exception handlers cannot reliably be found in Java |
| bytecode. Instead of removing the handler join point entirely, the |
| current AspectJ compiler restricts what can be done with the handler |
| join point: |
| </p><div class="itemizedlist"><ul><li><a name="d0e7299"></a>After and around advice cannot apply to handler |
| join points.</li><li><a name="d0e7301"></a>The control flow of a handler join point cannot be |
| detected. </li></ul></div><p> |
| The first of these is relatively straightforward. If any piece of |
| after advice (returning, throwing, or "finally") would normally |
| apply to a handler join point, it will not in code output by the |
| current AspectJ compiler. A compiler warning is generated whenever |
| this is detected to be the case. Before advice is allowed. |
| </p><p> The second is that the control flow of a handler join point |
| is not picked out. For example, the following pointcut |
| </p><pre class="programlisting"> |
| cflow(call(void foo()) || handler(java.io.IOException)) |
| </pre><p> will capture all join points in the control flow of a call to |
| <tt>void foo()</tt>, but it will <span class="emphasis"><i>not</i></span> |
| capture those in the control flow of an |
| <tt>IOException</tt> handler. It is equivalent to |
| <tt>cflow(call(void foo()))</tt>. In general, |
| <tt>cflow(handler(<i><tt>Type</tt></i>))</tt> |
| will not pick out any join points, the one exception to this is join points |
| that occur during the execution of any before advice on the handler. |
| </p><p> This does not restrict programs from placing before advice on |
| handlers inside <span class="emphasis"><i>other</i></span> control flows. This |
| advice, for example, is perfectly fine: |
| </p><pre class="programlisting"> |
| before(): handler(java.io.IOException) && cflow(void parse()) { |
| System.out.println("about to handle an exception while parsing"); |
| } |
| </pre><p> |
| A source-code implementation of AspectJ (such as AspectJ 1.0.6) is |
| able to detect the endpoint of a handler join point, and as such |
| will likely have fewer such restrictions. |
| </p></div><div class="sect2"><a name="initializers-and-inter-type-constructors"></a><div class="titlepage"><div><h3 class="title"><a name="initializers-and-inter-type-constructors"></a>Initializers and Inter-type Constructors</h3></div></div><p> |
| The code for Java initializers, such as the assignment to the |
| field d in |
| </p><pre class="programlisting"> |
| class C { |
| double d = Math.sqrt(2); |
| } |
| </pre><p> |
| are considered part of constructors by the time AspectJ gets ahold |
| of bytecode. That is, the assignment of d to the square root of |
| two happens <span class="emphasis"><i>inside</i></span> the default constructor of |
| C. |
| </p><p> |
| Thus inter-type constructors will not necessarily run a target |
| type's initialization code. In particular, if the inter-type |
| constructor calls a super-constructor (as opposed to a |
| <tt>this</tt> constructor), the target type's |
| initialization code will <span class="emphasis"><i>not</i></span> be run when that |
| inter-type constructor is called. |
| </p><pre class="programlisting"> |
| aspect A { |
| C.new(Object o) {} // implicitly calls super() |
| |
| public static void main(String[] args) { |
| System.out.println((new C() ).d); // prints 1.414... |
| System.out.println((new C(null)).d); // prints 0.0 |
| } |
| </pre><p> |
| It is the job of an inter-type constructor to do all the required |
| initialization, or to delegate to a <tt>this</tt> |
| constructor if necessary. |
| </p></div></div><div class="sect1"><a name="d0e7365"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="d0e7365"></a>Summary of implementation requirements</h2></div></div><p> |
| This summarizes the requirements of our implementation of AspectJ. |
| For more details, see the relevant sections of this guide. |
| </p><div class="itemizedlist"><ul compact><li><p><a name="d0e7371"></a>The invoking code must be under the control of ajc |
| for the following join points:</p><div class="itemizedlist"><ul compact><li><a name="d0e7375"></a>call join point</li><li><a name="d0e7377"></a>get join point</li><li><a name="d0e7379"></a>set join point</li></ul></div></li><li><p><a name="d0e7381"></a>The declaring/target code must be under the control of ajc |
| for the following join points and inter-type declarations:</p><div class="itemizedlist"><ul compact><li><a name="d0e7385"></a>execution join point</li><li><a name="d0e7387"></a>adviceexecution join point</li><li><a name="d0e7389"></a>handler join point</li><li><a name="d0e7391"></a>initialization join point</li><li><a name="d0e7393"></a>preinitialiaztion join point</li><li><a name="d0e7395"></a>staticinitialization join point</li><li><a name="d0e7397"></a>perthis aspect</li><li><a name="d0e7399"></a>pertarget aspect</li><li><a name="d0e7401"></a>declare parents</li><li><a name="d0e7403"></a>declare method or field (see interface caveats below)</li></ul></div></li><li><p><a name="d0e7405"></a>Implementation Caveats</p><div class="itemizedlist"><ul compact><li><p><a name="d0e7409"></a>The initialization and preinitialization join points |
| do not support around advice</p></li><li><p><a name="d0e7412"></a>The handler join point does not support...</p><div class="itemizedlist"><ul compact><li><a name="d0e7416"></a>after advice</li><li><a name="d0e7418"></a>around advice</li><li><a name="d0e7420"></a>cflow(handler(..))</li></ul></div></li><li><p><a name="d0e7422"></a>Declaring members on an interface in an aspect affects only |
| the topmost implementing classes the implementation controls.</p></li><li><p><a name="d0e7425"></a>cflow and cflowbelow pointcuts work within a single thread.</p></li></ul></div></li></ul></div></div></div></div></body></html> |