diff options
author | Alexander Kriegisch <Alexander@Kriegisch.name> | 2024-02-01 11:57:10 +0700 |
---|---|---|
committer | Alexander Kriegisch <Alexander@Kriegisch.name> | 2024-02-01 11:57:10 +0700 |
commit | bbe629bc4a5e8c76a0b31686eedc88add5d71360 (patch) | |
tree | c03cca36ccdd16f37e23ff66c191381a41b5ed8a /docs/progguide | |
parent | d6056515f8078572dd35cd091fb31ba48e9d8b53 (diff) | |
download | aspectj-bbe629bc4a5e8c76a0b31686eedc88add5d71360.tar.gz aspectj-bbe629bc4a5e8c76a0b31686eedc88add5d71360.zip |
Always use ":leveloffset: +1" with ":doctype: book"
Headlines per ADOC file should start at level 1, not 2. Adjusting the
level offset for books helps to avoid warnings when including book
chapters, but still allows to also use the chapters as stand-alone
documents.
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'docs/progguide')
-rw-r--r-- | docs/progguide/examples.adoc | 98 | ||||
-rw-r--r-- | docs/progguide/gettingstarted.adoc | 40 | ||||
-rw-r--r-- | docs/progguide/idioms.adoc | 4 | ||||
-rw-r--r-- | docs/progguide/implementation.adoc | 16 | ||||
-rw-r--r-- | docs/progguide/index.adoc | 2 | ||||
-rw-r--r-- | docs/progguide/language.adoc | 36 | ||||
-rw-r--r-- | docs/progguide/pitfalls.adoc | 6 | ||||
-rw-r--r-- | docs/progguide/preface.adoc | 2 | ||||
-rw-r--r-- | docs/progguide/progguide.adoc | 2 | ||||
-rw-r--r-- | docs/progguide/quickreference.adoc | 14 | ||||
-rw-r--r-- | docs/progguide/semantics.adoc | 134 |
11 files changed, 177 insertions, 177 deletions
diff --git a/docs/progguide/examples.adoc b/docs/progguide/examples.adoc index caa74a620..98b7f6a3a 100644 --- a/docs/progguide/examples.adoc +++ b/docs/progguide/examples.adoc @@ -1,8 +1,8 @@ [[examples]] -== Examples += Examples [[examples-intro]] -=== Introduction +== Introduction This chapter consists entirely of examples of AspectJ use. @@ -18,7 +18,7 @@ reusable:: Examples of reuse of aspects and pointcuts [[examples-howto]] -=== Obtaining, Compiling and Running the Examples +== Obtaining, Compiling and Running the Examples The examples source code is part of the AspectJ distribution which may be downloaded from the https://eclipse.org/aspectj[AspectJ project page]. @@ -51,7 +51,7 @@ java -classpath ".;InstallDir/lib/aspectjrt.jar" telecom.billingSimulation .... [[examples-basic]] -=== Basic Techniques +== Basic Techniques This section presents two basic techniques of using AspectJ, one each from the two fundamental ways of capturing crosscutting concerns: with @@ -65,7 +65,7 @@ some advice. The second example, xref:#examples-roles[Roles and Views], concerns a crosscutting view of an existing class hierarchy. [[examples-joinPoints]] -==== Join Points and `thisJoinPoint` +=== Join Points and `thisJoinPoint` (The code for this example is in `InstallDir/examples/tjp`.) @@ -125,7 +125,7 @@ point * an object encapsulating the static information about the join point. This is also available through the special variable `thisJoinPointStaticPart`. -===== The `Demo` class +==== The `Demo` class The class `tjp.Demo` in `tjp/Demo.java` defines two methods `foo` and `bar` with different parameter lists and return types. Both are called, @@ -158,7 +158,7 @@ public class Demo { } .... -===== The `GetInfo` aspect +==== The `GetInfo` aspect This aspect uses around advice to intercept the execution of methods `foo` and `bar` in `Demo`, and prints out information garnered from @@ -201,7 +201,7 @@ aspect GetInfo { } .... -====== Defining the scope of a pointcut +===== Defining the scope of a pointcut The pointcut `goCut` is defined as @@ -216,7 +216,7 @@ execution of `go` itself, so the definition of the around advice includes `!execution(* go())` to exclude it from the set of executions advised. -====== Printing the class and method name +===== Printing the class and method name The name of the method and that method's defining class are available as parts of the @@ -224,7 +224,7 @@ xref:../api/org/aspectj/lang/Signature.html[`org.aspectj.lang.Signature`] object returned by calling `getSignature()` on either `thisJoinPoint` or `thisJoinPointStaticPart`. -====== Printing the parameters +===== Printing the parameters The static portions of the parameter details, the name and types of the parameters, can be accessed through the @@ -236,7 +236,7 @@ The dynamic portions of the parameter details, the actual values of the parameters, are accessed directly from the execution join point object. [[examples-roles]] -==== Roles and Views +=== Roles and Views (The code for this example is in `InstallDir/examples/introduction`.) @@ -269,7 +269,7 @@ and polar coordinates. Our inter-type declarations will make the class are provided by AspectJ without having to modify the code for the class `Point`. -===== The `Point` class +==== The `Point` class The `Point` class defines geometric points whose interface includes polar and rectangular coordinates, plus some simple operations to @@ -289,7 +289,7 @@ with the class `Point`. image:images/aspects.png[image] -===== The `CloneablePoint` aspect +==== The `CloneablePoint` aspect This first aspect is responsible for ``Point``'s implementation of the `Cloneable` interface. It declares that `Point implements Cloneable` @@ -336,7 +336,7 @@ public aspect CloneablePoint { } .... -===== The `ComparablePoint` aspect +==== The `ComparablePoint` aspect `ComparablePoint` is responsible for ``Point``'s implementation of the `Comparable` interface. @@ -387,7 +387,7 @@ public aspect ComparablePoint { } .... -===== The `HashablePoint` aspect +==== The `HashablePoint` aspect Our third aspect is responsible for ``Point``'s overriding of ``Object``'s `equals` and `hashCode` methods in order to make ``Point``s hashable. @@ -450,9 +450,9 @@ public aspect HashablePoint { .... [[examples-development]] -=== Development Aspects +== Development Aspects -==== Tracing using aspects +=== Tracing using aspects (The code for this example is in `InstallDir/examples/tracing`.) @@ -482,7 +482,7 @@ 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. -===== An Example Application +==== An Example Application Throughout this example we will use a simple application that contains only four classes. The application is about shapes. The `TwoDShape` @@ -586,7 +586,7 @@ s1.distance(c1) = 2.23606797749979 s1.toString(): Square side = 1.0 @ (1.0, 2.0) .... -===== Tracing - Version 1 +==== Tracing - Version 1 In a first attempt to insert tracing in this application, we will start by writing a `Trace` class that is exactly what we would write if we @@ -707,7 +707,7 @@ s1.toString(): Square side = 1.0 @ (1.0, 2.0) When `TraceMyClasses.java` is not provided to `ajc`, the aspect does not have any affect on the system and the tracing is unplugged. -===== Tracing - Version 2 +==== Tracing - Version 2 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, @@ -846,9 +846,9 @@ Abstract methods don't provide the implementation, but you know that the concrete subclasses will, so you can invoke those methods. [[examples-production]] -=== Production Aspects +== Production Aspects -==== A Bean Aspect +=== A Bean Aspect (The code for this example is in `InstallDir/examples/bean`.) @@ -876,7 +876,7 @@ class is not serializable. Bound is an aspect that makes `Point` a serializable class and makes its `get` and `set` methods support the bound property protocol. -===== The `Point` class +==== The `Point` class The `Point` class is a very simple class with trivial getters and setters, and a simple vector offset method. @@ -919,7 +919,7 @@ class Point { } .... -===== The `BoundPoint` aspect +==== The `BoundPoint` aspect The `BoundPoint` aspect is responsible for ``Point``'s "beanness". The first thing it does is privately declare that each `Point` has a @@ -1023,7 +1023,7 @@ aspect BoundPoint { } .... -===== The Test Program +==== The Test Program The test program registers itself as a property change listener to a `Point` object that it creates and then performs simple manipulation of @@ -1064,7 +1064,7 @@ class Demo implements PropertyChangeListener { } .... -===== Compiling and Running the Example +==== Compiling and Running the Example To compile and run this example, go to the examples directory and type: @@ -1075,7 +1075,7 @@ java bean.Demo .... [[the-subject-observer-protocol]] -==== The Subject/Observer Protocol +=== The Subject/Observer Protocol (The code for this example is in `InstallDir/examples/observer`.) @@ -1095,7 +1095,7 @@ 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. -===== Generic Components +==== Generic Components The generic parts of the protocol are the interfaces `Subject` and `Observer`, and the abstract aspect `SubjectObserverProtocol`. The @@ -1165,7 +1165,7 @@ after the join points of the pointcut. And it declares an inter-type field and two inter-type methods so that each `Observer` can hold onto its `Subject`. -===== Application Classes +==== Application Classes `Button` objects extend `java.awt.Button`, and all they do is make sure the `void click()` method is called whenever a button is clicked. @@ -1255,7 +1255,7 @@ required by those interfaces, and providing a definition for the abstract `stateChanges` pointcut. Now, every time a `Button` is clicked, all `ColorLabel` objects observing that button will `colorCycle`. -===== Compiling and Running +==== Compiling and Running `Demo` is the top class that starts this demo. It instantiates a two buttons and three observers and links them together as subjects and @@ -1267,7 +1267,7 @@ ajc -argfile observer/files.lst java observer.Demo .... -==== A Simple Telecom Simulation +=== A Simple Telecom Simulation (The code for this example is in `InstallDir/examples/telecom`.) @@ -1277,7 +1277,7 @@ model of telephone connections to which timing and billing features are added using aspects, where the billing feature depends upon the timing feature. -===== The Application +==== The Application The example application is a simple simulation of a telephony system in which customers make, accept, merge and hang-up both local and long @@ -1303,7 +1303,7 @@ share a common superclass `AbstractSimulation`, which defines the method run with the simulation itself and the method wait used to simulate elapsed time. -===== The Basic Objects +==== The Basic Objects The telecom simulation comprises the classes `Customer`, `Call` and the abstract class `Connection` with its two concrete subclasses `Local` and @@ -1316,7 +1316,7 @@ involved in many calls at one time. image:images/telecom.png[image] -===== The `Customer` class +==== The `Customer` class `Customer` has methods `call`, `pickup`, `hangup` and `merge` for managing calls. @@ -1377,7 +1377,7 @@ public class Customer { } .... -===== The `Call` class +==== The `Call` class 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 @@ -1387,7 +1387,7 @@ 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. -===== The `Connection` class +==== The `Connection` class The class `Connection` models the physical details of establishing a connection between customers. It does this with a simple state machine @@ -1437,7 +1437,7 @@ abstract class Connection { } .... -===== The `Local` and `LongDistance` classes +==== The `Local` and `LongDistance` classes The two kinds of connections supported by our simulation are `Local` and `LongDistance` connections. @@ -1466,7 +1466,7 @@ class LongDistance extends Connection { } .... -===== Compiling and Running the Basic Simulation +==== Compiling and Running the Basic Simulation The source files for the basic system are listed in the file `basic.lst`. To build and run the basic system, in a shell window, type @@ -1478,13 +1478,13 @@ ajc -argfile telecom/basic.lst java telecom.BasicSimulation .... -===== The Timing aspect +==== The Timing aspect The `Timing` aspect keeps track of total connection time for each `Customer` by starting and stopping a timer associated with each connection. It uses some helper classes: -====== The `Timer` class +===== The `Timer` class A `Timer` object simply records the current time when it is started and stopped, and returns their difference when asked for the elapsed time. @@ -1511,7 +1511,7 @@ class Timer { } .... -===== The `TimerLog` aspect +==== The `TimerLog` aspect The `TimerLog` aspect can be included in a build to get the timer to announce when it is started and stopped. @@ -1530,7 +1530,7 @@ public aspect TimerLog { } .... -===== The `Timing` aspect +==== The `Timing` aspect The `Timing` aspect is declares an inter-type field `totalConnectTime` for `Customer` to store the accumulated connection time per `Customer`. @@ -1573,7 +1573,7 @@ public aspect Timing { } .... -===== The `Billing` aspect +==== The `Billing` aspect The Billing system adds billing functionality to the telecom application on top of timing. @@ -1627,7 +1627,7 @@ public aspect Billing { } .... -===== Accessing the inter-type state +==== Accessing the inter-type state Both the aspects `Timing` and `Billing` contain the definition of operations that the rest of the system may want to access. For example, @@ -1651,7 +1651,7 @@ protected void report(Customer c){ } .... -===== Compiling and Running +==== Compiling and Running The files timing.lst and billing.lst contain file lists for the timing and billing configurations. To build and run the application with only @@ -1672,7 +1672,7 @@ ajc -argfile telecom/billing.lst java telecom.BillingSimulation .... -===== Discussion +==== Discussion There are some explicit dependencies between the aspects `Billing` and `Timing`: @@ -1683,13 +1683,13 @@ advice runs after that of `Timing` when they are on the same join point. * `Billing` needs access to the timer associated with a connection. [[examples-reusable]] -=== Reusable Aspects +== Reusable Aspects -==== Tracing using Aspects, Revisited +=== Tracing using Aspects, Revisited (The code for this example is in `InstallDir/examples/tracing`.) -===== Tracing - Version 3 +==== Tracing - Version 3 One advantage of not exposing the methods `traceEntry` and `traceExit` as public operations is that we can easily change their interface without diff --git a/docs/progguide/gettingstarted.adoc b/docs/progguide/gettingstarted.adoc index b7de29e59..b74006724 100644 --- a/docs/progguide/gettingstarted.adoc +++ b/docs/progguide/gettingstarted.adoc @@ -1,8 +1,8 @@ [[starting]] -== Getting Started with AspectJ += Getting Started with AspectJ [[starting-intro]] -=== Introduction +== Introduction Many software developers are attracted to the idea of aspect-oriented programming (AOP) but unsure about how to begin using the technology. @@ -48,7 +48,7 @@ is one ordering that allows developers to get experience with (and benefit from) AOP technology quickly, while also minimizing risk. [[starting-aspectj]] -=== Introduction to AspectJ +== Introduction to AspectJ This section presents a brief introduction to the features of AspectJ used later in this chapter. These features are at the core of the @@ -114,7 +114,7 @@ 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. -==== The Dynamic Join Point Model +=== The Dynamic Join Point Model 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 @@ -138,7 +138,7 @@ from the body. We say that these join points execute in the _dynamic context_ of the original call join point. [[pointcuts-starting]] -==== Pointcuts +=== Pointcuts In AspectJ, _pointcuts_ pick out certain join points in the program flow. For example, the pointcut @@ -239,7 +239,7 @@ called and when it returns (either normally or by throwing an exception). [[advice-starting]] -==== Advice +=== Advice So pointcuts pick out join points. But they don't _do_ anything apart from picking out join points. To actually implement crosscutting @@ -279,7 +279,7 @@ _Around advice_ 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. -===== Exposing Context in Pointcuts +==== Exposing Context in Pointcuts 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 @@ -353,7 +353,7 @@ after(FigureElement fe, int x, int y) returning: setXY(fe, x, y) { } .... -==== Inter-type declarations +=== Inter-type declarations Inter-type declarations in AspectJ are declarations that cut across classes and their hierarchies. They may declare members that cut across @@ -440,7 +440,7 @@ Note that neither ``Screen``'s nor ``Point``'s code has to be modified, and that all the changes needed to support this new capability are local to this aspect. -==== Aspects +=== Aspects Aspects wrap up pointcuts, advice, and inter-type declarations in a a modular unit of crosscutting implementation. It is defined very much @@ -469,7 +469,7 @@ Aspects may also have more complicated rules for instantiation, but these will be described in a later chapter. [[starting-development]] -=== Development Aspects +== Development Aspects The next two sections present the use of aspects in increasingly sophisticated ways. Development aspects are easily removed from @@ -484,7 +484,7 @@ 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. -==== Tracing +=== Tracing 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 @@ -537,7 +537,7 @@ 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. -==== Profiling and Logging +=== Profiling and Logging Our second example shows you how to do some very specific profiling. Although many sophisticated profiling tools are available, and these can @@ -588,7 +588,7 @@ Such questions may be difficult to express using standard profiling or logging tools. [[pre-and-post-conditions]] -==== Pre- and Post-Conditions +=== Pre- and Post-Conditions Many programmers use the "Design by Contract" style popularized by Bertand Meyer in Object-Oriented Software Construction, 2/e. In this @@ -637,7 +637,7 @@ 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. -==== Contract Enforcement +=== Contract Enforcement The property-based crosscutting mechanisms can be very useful in defining more sophisticated contract enforcement. One very powerful use @@ -692,7 +692,7 @@ and the `call` 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. -==== Configuration Management +=== Configuration Management Configuration management for aspects can be handled using a variety of make-file like techniques. To work with optional aspects, the programmer @@ -706,7 +706,7 @@ to write such make files, the AspectJ compiler has a command-line interface that is consistent with ordinary Java compilers. [[starting-production]] -=== Production Aspects +== Production Aspects This section presents examples of aspects that are inherently intended to be included in the production builds of an application. Production @@ -719,7 +719,7 @@ 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. -==== Change Monitoring +=== Change Monitoring The first example production aspect shows how one might implement some simple functionality where it is problematic to try and do it @@ -803,7 +803,7 @@ compelling for property-based aspects (see the section xref:#starting-production-consistentBehavior[Providing Consistent Behavior]). -==== Context Passing +=== Context Passing The crosscutting structure of context passing can be a significant source of complexity in Java programs. Consider implementing @@ -844,7 +844,7 @@ aspects while the aspect is short and affects only a modest number of benefits, the complexity the aspect saves is potentially much larger. [[starting-production-consistentBehavior]] -==== Providing Consistent Behavior +=== Providing Consistent Behavior This example shows how a property-based aspect can be used to provide consistent handling of functionality across a large set of operations. @@ -935,7 +935,7 @@ crosscutting structure of the aspect explicitly made the code more concise and eliminated latent bugs. [[starting-conclusion]] -=== Conclusion +== Conclusion AspectJ is a simple and practical aspect-oriented extension to Java. With just a few new constructs, AspectJ provides support for modular diff --git a/docs/progguide/idioms.adoc b/docs/progguide/idioms.adoc index e27395a48..a264084e0 100644 --- a/docs/progguide/idioms.adoc +++ b/docs/progguide/idioms.adoc @@ -1,7 +1,7 @@ -== Idioms += Idioms [[idioms-intro]] -=== Introduction +== Introduction This chapter consists of very short snippets of AspectJ code, typically pointcuts, that are particularly evocative or useful. This section is a diff --git a/docs/progguide/implementation.adoc b/docs/progguide/implementation.adoc index 42ee2e37e..03a0e19ae 100644 --- a/docs/progguide/implementation.adoc +++ b/docs/progguide/implementation.adoc @@ -1,7 +1,7 @@ [[implementation]] -== Implementation Notes += Implementation Notes -=== Compiler Notes +== Compiler Notes The initial implementations of AspectJ have all been compiler-based implementations. Certain elements of AspectJ's semantics are difficult @@ -108,10 +108,10 @@ 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. -=== Bytecode Notes +== Bytecode Notes [[the-class-expression-and-string-plus]] -==== The `.class` expression and `String` `+` +=== The `.class` expression and `String` `+` The java language form `Foo.class` is implemented in bytecode with a call to `Class.forName` guarded by an exception handler catching a @@ -140,7 +140,7 @@ class Test { In short, the join point model of the current AspectJ compiler considers these as valid join points. -==== The `handler()` join point +=== The `handler()` join point The end of exception handlers cannot reliably be found in Java bytecode. Instead of removing the `handler` join point entirely, the current AspectJ @@ -185,7 +185,7 @@ 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. -==== Initializers and Inter-type Constructors +=== Initializers and Inter-type Constructors The code for Java initializers, such as the assignment to the field `d` in @@ -221,7 +221,7 @@ aspect A { It is the job of an inter-type constructor to do all the required initialization, or to delegate to a `this` constructor if necessary. -=== Annotation-style Notes +== Annotation-style Notes Writing aspects in annotation-style is subject to the same bytecode limitations since the binary aspects take the same form and are woven in @@ -229,7 +229,7 @@ the same way. However, the implementation differences (e.g., the mechanism for implementing `around` advice) may be apparent at runtime. See the documentation on annotation-style for more information. -=== Summary of implementation requirements +== Summary of implementation requirements This summarizes the requirements of our implementation of AspectJ. For more details, see the relevant sections of this guide. diff --git a/docs/progguide/index.adoc b/docs/progguide/index.adoc index eb1b42375..11ba5afd8 100644 --- a/docs/progguide/index.adoc +++ b/docs/progguide/index.adoc @@ -1,6 +1,6 @@ = The AspectJ^TM^ Programming Guide - :doctype: book +:leveloffset: +1 _by the AspectJ Team_ diff --git a/docs/progguide/language.adoc b/docs/progguide/language.adoc index 14b662aad..72a49e813 100644 --- a/docs/progguide/language.adoc +++ b/docs/progguide/language.adoc @@ -1,8 +1,8 @@ [[language]] -== The AspectJ Language += The AspectJ Language [[language-intro]] -=== Introduction +== Introduction The previous chapter, xref:gettingstarted.adoc#starting[Getting Started with AspectJ], was a brief overview of the AspectJ language. You should read this chapter to understand AspectJ's @@ -14,13 +14,13 @@ of a pointcut, an introduction, and two pieces of advice. This example aspect will gives us something concrete to talk about. [[language-anatomy]] -=== The Anatomy of an Aspect +== The Anatomy of an Aspect 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. -==== An Example Aspect +=== An Example Aspect Here's an example of an aspect definition in AspectJ: @@ -61,7 +61,7 @@ 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. -==== Pointcuts +=== Pointcuts AspectJ's pointcut definitions give names to pointcuts. Pointcuts themselves pick out join points, i.e. interesting points in the @@ -109,7 +109,7 @@ 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. -==== Advice +=== Advice 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 @@ -148,7 +148,7 @@ third kind of advice called around. You will see those in other parts of this guide. [[language-joinPoints]] -=== Join Points and Pointcuts +== Join Points and Pointcuts Consider the following Java class: @@ -221,7 +221,7 @@ 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. -==== Some Example Pointcuts +=== Some Example Pointcuts Here are examples of pointcuts picking out @@ -302,7 +302,7 @@ in ``MyInterface``'s signature -- that is, any method defined by `MyInterface` or inherited by one of its a supertypes. [[call-vs-execution]] -==== call vs. execution +=== call vs. execution When methods and constructors run, there are two interesting times associated with them. That is when they are called, and when they @@ -335,7 +335,7 @@ use `execution`, but if you want to pick one that runs when a particular _signature_ is called (as is often the case for production aspects), use `call`. -==== Pointcut composition +=== Pointcut composition Pointcuts are put together with the operators and (spelled `&&`), or (spelled `||`), and not (spelled `!`). This allows the creation of very @@ -426,7 +426,7 @@ If this was not present a recursive call would result as the pointcut would apply to its own advice. (See xref:pitfalls.adoc#pitfalls-infiniteLoops[Infinite loops] for more details.) -==== Pointcut Parameters +=== Pointcut Parameters Consider again the first pointcut definition in this chapter: @@ -520,7 +520,7 @@ when calling `setY`, but the pointcut picks out all of these join points and tries to bind both `p1` and `p2`. [[example]] -==== Example: `HandleLiveness` +=== Example: `HandleLiveness` The example below consists of two object classes (plus an exception class) and one aspect. Handle objects delegate their public, non-static @@ -561,7 +561,7 @@ class DeadPartnerException extends RuntimeException {} .... [[pointcut-best-practice]] -==== Writing good pointcuts +=== Writing good pointcuts During compilation, AspectJ processes pointcuts in order to try and optimize matching performance. Examining code and determining if each @@ -603,7 +603,7 @@ processed - that is why a good pointcut should always include one if possible. [[language-advice]] -=== Advice +== Advice Advice defines pieces of aspect implementation that execute at well-defined points in the execution of the program. Those points can be @@ -710,7 +710,7 @@ void around(Point p, int x): .... [[language-interType]] -=== Inter-type declarations +== Inter-type declarations Aspects can declare members (fields, methods, and constructors) that are owned by other types. These are called inter-type members. Aspects can @@ -820,7 +820,7 @@ 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. -==== Inter-type Scope +=== Inter-type Scope AspectJ allows private and package-protected (default) inter-type declarations in addition to public inter-type declarations. Private @@ -843,7 +843,7 @@ int Foo.x; then everything in the aspect's package (which may or may not be ``Foo``'s package) can access `x`. -==== Example: `PointAssertions` +=== Example: `PointAssertions` The example below consists of one class and one aspect. The aspect privately declares the assertion methods of `Point`, `assertX` and @@ -888,7 +888,7 @@ aspect PointAssertions { .... [[language-thisJoinPoint]] -=== `thisJoinPoint` +== `thisJoinPoint` AspectJ provides a special reference variable, `thisJoinPoint`, that contains reflective information about the current join point for the diff --git a/docs/progguide/pitfalls.adoc b/docs/progguide/pitfalls.adoc index eb9e15315..a80460c58 100644 --- a/docs/progguide/pitfalls.adoc +++ b/docs/progguide/pitfalls.adoc @@ -1,13 +1,13 @@ -== Pitfalls += Pitfalls [[pitfalls-intro]] -=== Introduction +== Introduction This chapter consists of a few AspectJ programs that may lead to surprising behavior and how to understand them. [[pitfalls-infiniteLoops]] -=== Infinite loops +== Infinite loops Here is a Java program with peculiar behavior diff --git a/docs/progguide/preface.adoc b/docs/progguide/preface.adoc index efeb18637..92f0c1da0 100644 --- a/docs/progguide/preface.adoc +++ b/docs/progguide/preface.adoc @@ -1,4 +1,4 @@ -== Preface += Preface This programming guide does three things. It diff --git a/docs/progguide/progguide.adoc b/docs/progguide/progguide.adoc index 2e595edb6..6099dd5f1 100644 --- a/docs/progguide/progguide.adoc +++ b/docs/progguide/progguide.adoc @@ -1,6 +1,6 @@ = The AspectJ^TM^ Programming Guide - :doctype: book +:leveloffset: +1 _by the AspectJ Team_ diff --git a/docs/progguide/quickreference.adoc b/docs/progguide/quickreference.adoc index 3920b5ef2..d1a16066d 100644 --- a/docs/progguide/quickreference.adoc +++ b/docs/progguide/quickreference.adoc @@ -1,8 +1,8 @@ [[quick]] -== AspectJ Quick Reference += AspectJ Quick Reference [[quick-pointcuts]] -=== Pointcuts +== Pointcuts [cols=",",] |=== @@ -56,7 +56,7 @@ or constructor matching `Signature` |=== [[quick-typePatterns]] -=== Type Patterns +== Type Patterns A type pattern is one of @@ -90,7 +90,7 @@ An embedded `..` in an identifier matches any sequence of characters that starts and ends with the package (or inner-type) separator `.`. [[quick-advice]] -=== Advice +== Advice Each piece of advice is of the form @@ -130,7 +130,7 @@ Three special variables are available inside of advice bodies: the static part of the dynamically enclosing join point [[quick-interType]] -=== Inter-type member declarations +== Inter-type member declarations Each inter-type member is one of @@ -144,7 +144,7 @@ Each inter-type member is one of a field on `OnType` [[quick-other]] -=== Other declarations +== Other declarations `declare parents : TypePattern extends Type ;`:: the types in `TypePattern` extend `Type` @@ -164,7 +164,7 @@ Each inter-type member is one of precedence at that join point is in `TypePatternList` order [[quick-aspectAssociations]] -=== Aspects +== Aspects Each aspect is of the form diff --git a/docs/progguide/semantics.adoc b/docs/progguide/semantics.adoc index 0cb513ad0..d993d2fcb 100644 --- a/docs/progguide/semantics.adoc +++ b/docs/progguide/semantics.adoc @@ -1,8 +1,8 @@ [[semantics]] -== Language Semantics += Language Semantics [[semantics-intro]] -=== Introduction +== Introduction AspectJ extends Java by overlaying a concept of join points onto the existing Java semantics and adding a few new program elements to Java: @@ -35,7 +35,7 @@ possible to do reasoning at compile time. Aspects are defined by the `aspect` declaration. [[semantics-joinPoints]] -=== Join Points +== Join Points While aspects define types that crosscut, the AspectJ system does not allow completely arbitrary crosscutting. Rather, aspects define types @@ -152,7 +152,7 @@ bodies or static initializers. methods or fields. [[semantics-pointcuts]] -=== Pointcuts +== Pointcuts 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 @@ -233,7 +233,7 @@ provided by the language are: `( Pointcut )`:: Picks out each join points picked out by `_Pointcut_` . -==== Pointcut definition +=== Pointcut definition Pointcuts are defined and named by the programmer with the `pointcut` declaration. @@ -300,7 +300,7 @@ aspect B percflow(publicCall()) { } .... -==== Context exposure +=== Context exposure Pointcuts have an interface; they expose some parts of the execution context of the join points they pick out. For example, the PublicIntCall @@ -384,9 +384,9 @@ aspect IntToLong { The pointcut will match and expose the integer argument, but it will expose it as an `Integer`, not a `Long`. -==== Primitive pointcuts +=== Primitive pointcuts -===== Method-related pointcuts +==== Method-related pointcuts AspectJ provides two primitive pointcut designators designed to capture method call and execution join points. @@ -394,7 +394,7 @@ method call and execution join points. * `call( MethodPattern )` * `execution( MethodPattern )` -===== Field-related pointcuts +==== Field-related pointcuts AspectJ provides two primitive pointcut designators designed to capture field reference and set join points: @@ -419,7 +419,7 @@ aspect GuardedX { } .... -===== Object creation-related pointcuts +==== Object creation-related pointcuts AspectJ provides primitive pointcut designators designed to capture the initializer execution join points of objects. @@ -429,14 +429,14 @@ initializer execution join points of objects. * `initialization( ConstructorPattern )` * `preinitialization( ConstructorPattern )` -===== Class initialization-related pointcuts +==== Class initialization-related pointcuts AspectJ provides one primitive pointcut designator to pick out static initializer execution join points. * `staticinitialization( TypePattern )` -===== Exception handler execution-related pointcuts +==== Exception handler execution-related pointcuts AspectJ provides one primitive pointcut designator to capture execution of exception handlers: @@ -457,7 +457,7 @@ aspect NormalizeFooException { } .... -===== Advice execution-related pointcuts +==== Advice execution-related pointcuts AspectJ provides one primitive pointcut designator to capture execution of advice @@ -478,7 +478,7 @@ aspect TraceStuff { } .... -===== State-based pointcuts +==== State-based pointcuts Many concerns cut across the dynamic times when an object of a particular type is executing, being operated on, or being passed around. @@ -521,7 +521,7 @@ args(int, .., String) will pick out all join points where the first argument is an `int` and the last is a `String`. -===== Control flow-based pointcuts +==== Control flow-based pointcuts Some concerns cut across the control flow of the program. The `cflow` and `cflowbelow` primitive pointcut designators capture join points @@ -540,7 +540,7 @@ entry and exit of each join point `P` picked out by `Pointcut`, but not including `P` itself. Hence, it picks out the join points _below_ the control flow of the join points picked out by `Pointcut`. -====== Context exposure from control flows +===== Context exposure from control flows The `cflow` and `cflowbelow` pointcuts may expose context state through enclosed `this`, `target`, and `args` pointcuts. @@ -577,7 +577,7 @@ aspect A { It is an error to expose such state through _negated_ control flow pointcuts, such as within `!cflowbelow(P)`. -===== Program text-based pointcuts +==== Program text-based pointcuts While many concerns cut across the runtime structure of the program, some must deal with the lexical structure. AspectJ allows aspects to @@ -603,7 +603,7 @@ 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. -===== Expression-based pointcuts +==== Expression-based pointcuts * `if( BooleanExpression )` @@ -623,13 +623,13 @@ a join point is undefined. Writing `if` 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. -==== Signatures +=== Signatures 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. -===== Methods +==== Methods Join points associated with methods typically have method signatures, consisting of a method name, parameter types, return type, the types of @@ -645,7 +645,7 @@ means that the signature for the join point created from the call At a method execution join point, the signature is a method signature whose qualifying type is the declaring type of the method. -===== Fields +==== Fields Join points associated with fields typically have field signatures, consisting of a field name and a field type. A field reference join @@ -653,7 +653,7 @@ 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. -===== Constructors +==== Constructors Join points associated with constructors typically have constructor signatures, consisting of a parameter types, the types of the declared @@ -669,7 +669,7 @@ signature is the constructor signature for the constructor that started this initialization: the first constructor entered during this type's initialization of this object. -===== Others +==== Others At a handler execution join point, the signature is composed of the exception type that the handler handles. @@ -679,7 +679,7 @@ 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. -==== Matching +=== Matching The `withincode`, `call`, `execution`, `get`, and `set` primitive pointcut designators all use signature patterns to determine the join @@ -796,7 +796,7 @@ private null constructor of a class `C` defined to throw an execution(private C.new() throws ArithmeticException) .... -===== Matching based on the declaring type +==== Matching based on the declaring type The signature-matching pointcuts all specify a declaring type, but the meaning varies slightly for each join point signature, in line with Java @@ -869,7 +869,7 @@ class Sub extends Middle { } .... -===== Matching based on the `throws` clause +==== Matching based on the `throws` clause Type patterns may be used to pick out methods and constructors based on their `throws` clauses. This allows the following two kinds of extremely @@ -927,13 +927,13 @@ declares that it `throws IOException`. [2] *will* match the method `m()`, because ``m``'s throws clause declares that it throws some exception which does not match `IOException`, i.e. `RuntimeException`. -==== Type patterns +=== Type patterns 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. -===== Exact type pattern +==== Exact type pattern First, all type names are also type patterns. So `Object`, `java.util.HashMap`, `Map.Entry`, `int` are all type patterns. @@ -953,7 +953,7 @@ then the matching works just like normal type lookup in Java: So exact type patterns match based on usual Java scope rules. -===== Type name patterns +==== Type name patterns There is a special type name, `\*`, which is also a type pattern. `*` picks out all types, including primitive types. So @@ -1004,7 +1004,7 @@ 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. -===== Subtype patterns +==== Subtype patterns It is possible to pick out all subtypes of a type (or a collection of types) with the `+` wildcard. The `+` wildcard follows immediately a @@ -1034,13 +1034,13 @@ call(*Handler+.new()) picks out all constructor call join points where an instance of any subtype of any type whose name ends in `Handler` is constructed. -===== Array type patterns +==== Array type patterns A type name pattern or subtype pattern can be followed by one or more sets of square brackets to make array type patterns. So `Object[]` is an array type pattern, and so is `com.xerox..*[][]`, and so is `Object+[]`. -===== Type patterns +==== Type patterns Type patterns are built up out of type name patterns, subtype patterns, and array type patterns, and constructed with boolean operators `&&`, @@ -1062,7 +1062,7 @@ call((Foo+ && ! Foo).new(..)) picks out the constructor call join points when a subtype of `Foo`, but not `Foo` itself, is constructed. -==== Pattern Summary +=== Pattern Summary Here is a summary of the pattern syntax used in AspectJ: @@ -1093,7 +1093,7 @@ ModifiersPattern = .... [[semantics-advice]] -=== Advice +== Advice Each piece of advice is of the form @@ -1338,13 +1338,13 @@ prove that there won't be a runtime binary-compatible change in the hierarchy of `LinkedList` or some other advice on the join point that requires a `LinkedList`. -==== Advice modifiers +=== Advice modifiers The `strictfp` 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. -==== Advice and checked exceptions +=== Advice and checked exceptions An advice declaration must include a `throws` clause listing the checked exceptions the body may throw. This list of checked exceptions must be @@ -1394,12 +1394,12 @@ pre-initialization and initialization:: advice execution:: any exception that is in the `throws` clause of the advice. -==== Advice precedence +=== Advice precedence 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. -===== Determining precedence +==== Determining precedence 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. @@ -1438,7 +1438,7 @@ aspect A { such circularities will result in errors signalled by the compiler. -===== Effects of precedence +==== Effects of precedence At a particular join point, advice is ordered by precedence. @@ -1466,7 +1466,7 @@ Running `after` 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. -==== Reflective access to the join point +=== Reflective access to the join point Three special variables are visible within bodies of advice and within `if()` pointcut expressions: `thisJoinPoint`, `thisJoinPointStaticPart`, @@ -1503,14 +1503,14 @@ to `thisJoinPoint` is `org.aspectj.lang.JoinPoint`, while `org.aspectj.lang.JoinPoint.StaticPart`. [[semantics-declare]] -=== Static crosscutting +== Static crosscutting 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 `declare` forms. -==== Inter-type member declarations +=== Inter-type member declarations AspectJ allows the declaration of members by aspects that are associated with other types. @@ -1576,7 +1576,7 @@ inter-type field declaration, refers to the `OnType` object rather than to the aspect type; it is an error to access `this` in such a position from a `static` inter-type member declaration. -==== Access modifiers +=== Access modifiers Inter-type member declarations may be `public` or `private`, or have default (package-protected) visibility. AspectJ does not provide protected @@ -1604,7 +1604,7 @@ 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. -==== Conflicts +=== Conflicts Inter-type declarations raise the possibility of conflicts among locally declared members and inter-type members. For example, assuming @@ -1663,7 +1663,7 @@ This is true both when the precedence is declared explicitly with `declare precedence` as well as when when sub-aspects implicitly have precedence over their super-aspect. -==== Extension and Implementation +=== Extension and Implementation 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 @@ -1687,7 +1687,7 @@ aspect A { } .... -==== Interfaces with members +=== Interfaces with members Through the use of inter-type members, interfaces may now carry (non-public-static-final) fields and (non-public-abstract) methods that @@ -1721,7 +1721,7 @@ when a new `E` is instantiated, the initializers run in this order: Object M C O N D Q P E .... -==== Warnings and Errors +=== Warnings and Errors An aspect may specify that a particular join point should never be reached. @@ -1733,7 +1733,7 @@ If the compiler determines that a join point in `Pointcut` could possibly be reached, then it will signal either an error or warning, as declared, using the `String` for its message. -==== Softened exceptions +=== Softened exceptions An aspect may specify that a particular kind of exception, if thrown at a join point, should bypass Java's usual static exception checking @@ -1790,7 +1790,7 @@ abstract aspect A { .... [[advice-precedence-cross]] -==== Advice Precedence +=== Advice Precedence An aspect may declare a precedence relationship between concrete aspects with the `declare precedence` form: @@ -1844,7 +1844,7 @@ aspect CountEntry { } .... -===== Various cycles +==== Various cycles It is an error for any aspect to be matched by more than one TypePattern in a single decare precedence, so: @@ -1868,7 +1868,7 @@ 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. -===== Applies to concrete aspects +==== Applies to concrete aspects Consider the following library aspects: @@ -1922,7 +1922,7 @@ declare precedence: Logging+, Profiling+; are meaningful. -==== Statically determinable pointcuts +=== Statically determinable pointcuts Pointcuts that appear inside of `declare` forms have certain restrictions. Like other pointcuts, these pick out join points, but they @@ -1943,17 +1943,17 @@ defined in terms of all of which can discriminate on runtime information. [[semantics-aspects]] -=== Aspects +== Aspects An aspect is a crosscutting type defined by the `aspect` declaration. -==== Aspect Declaration +=== Aspect Declaration The `aspect` declaration is similar to the `class` declaration in that it defines a type and an implementation for that type. It differs in a number of ways: -===== Aspect implementation can cut across other types +==== Aspect implementation can cut across other types In addition to normal Java class declarations such as methods and fields, aspect declarations can include AspectJ declarations such as @@ -1961,45 +1961,45 @@ 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). -===== Aspects are not directly instantiated +==== Aspects are not directly instantiated 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. -===== Nested aspects must be `static` +==== Nested aspects must be `static` 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 _must_ be defined with the `static` keyword. Local and anonymous aspects are not allowed. -==== Aspect Extension +=== Aspect Extension 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. -===== Aspects may extend classes and implement interfaces +==== Aspects may extend classes and implement interfaces 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. -===== Classes may not extend aspects +==== Classes may not extend aspects It is an error for a class to extend or implement an aspect. -===== Aspects extending aspects +==== Aspects extending aspects 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. -==== Aspect instantiation +=== Aspect instantiation Unlike class expressions, aspects are not instantiated with `new` expressions. Rather, aspect instances are automatically created to cut @@ -2015,7 +2015,7 @@ then by default the aspect is a singleton aspect. How an aspect is instantiated controls the form of the `aspectOf(..)` method defined on the concrete aspect class. -===== Singleton Aspects +==== Singleton Aspects * `aspect Id { ... }` * `aspect Id issingleton() { ... }` @@ -2035,7 +2035,7 @@ chance to run at all such join points. the aspect `A`, so there will be one instantiation for each time `A` is loaded by a different classloader.) -===== Per-object aspects +==== Per-object aspects * `aspect Id perthis( Pointcut ) { ... }` * `aspect Id pertarget( Pointcut ) { ... }` @@ -2062,7 +2062,7 @@ Both `perthis` and `pertarget` aspects may be affected by code the AspectJ compiler controls, as discussed in the xref:implementation.adoc#implementation[Implementation Notes] appendix. -===== Per-control-flow aspects +==== Per-control-flow aspects * `aspect Id percflow( Pointcut ) { ... }` * `aspect Id percflowbelow( Pointcut ) { ... }` @@ -2076,7 +2076,7 @@ under that control flow. During each such flow of control, the static method `A.aspectOf()` will return an object of type `A`. An instance of the aspect is created upon entry into each such control flow. -===== Aspect instantiation and advice +==== Aspect instantiation and advice 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 @@ -2111,7 +2111,7 @@ compile time. If advice runs before its aspect is instantiated, AspectJ will throw a xref:../api/org/aspectj/lang/NoAspectBoundException.html[`org.aspectj.lang.NoAspectBoundException`]. -==== Aspect privilege +=== Aspect privilege * `privileged aspect Id { ... }` |