| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>Development Aspects</title><link rel="stylesheet" href="aspectj-docs.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.44"><link rel="home" href="index.html" title="The AspectJTM Programming Guide"><link rel="up" href="starting.html" title="Chapter 1. Getting Started with AspectJ"><link rel="previous" href="starting-aspectj.html" title="Introduction to AspectJ"><link rel="next" href="starting-production.html" title="Production Aspects"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Development Aspects</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="starting-aspectj.html">Prev</a> </td><th width="60%" align="center">Chapter 1. Getting Started with AspectJ</th><td width="20%" align="right"> <a accesskey="n" href="starting-production.html">Next</a></td></tr></table><hr></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="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="starting-aspectj.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="starting-production.html">Next</a></td></tr><tr><td width="40%" align="left">Introduction to AspectJ </td><td width="20%" align="center"><a accesskey="u" href="starting.html">Up</a></td><td width="40%" align="right"> Production Aspects</td></tr></table></div></body></html> |