/usr/share/doc/aspectj-doc/progguide/starting-aspectj.html is in aspectj-doc 1.8.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Introduction to AspectJ</title><link rel="stylesheet" type="text/css" href="aspectj-docs.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><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="prev" href="starting.html" title="Chapter 1. Getting Started with AspectJ"><link rel="next" href="starting-development.html" title="Development 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">Introduction to AspectJ</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="starting.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-development.html">Next</a></td></tr></table><hr></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="starting-aspectj"></a>Introduction to AspectJ</h2></div></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
<code class="classname">Figure</code> consists of a number of
<code class="classname">FigureElements</code>, which can be either
<code class="classname">Point</code>s or <code class="classname">Line</code>s. The
<code class="classname">Figure</code> class provides factory services. There
is also a <code class="classname">Display</code>. Most example programs later
in this chapter are based on this system as well.
</p><p>
</p><div class="mediaobject"><img src="figureUML.gif"><div class="caption"><p>
UML for the <code class="literal">FigureEditor</code> example
</p></div></div><p>
</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"><em>join point</em></span> is a well-defined point in the
program flow. A <span class="emphasis"><em>pointcut</em></span> picks out certain join
points and values at those points. A piece of
<span class="emphasis"><em>advice</em></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"><em>inter-type
declarations</em></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"><em>aspect</em></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"><div class="titlepage"><div><div><h3 class="title"><a name="the-dynamic-join-point-model"></a>The Dynamic Join Point Model</h3></div></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"><em>dynamic context</em></span> of the
original call join point.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="pointcuts"></a>Pointcuts</h3></div></div></div><p>
In AspectJ, <span class="emphasis"><em>pointcuts</em></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 <code class="literal">void Point.setX(int)</code> — that is,
<code class="classname">Point</code>'s void <code class="function">setX</code>
method with a single <code class="literal">int</code> parameter.
</p><p>
A pointcut can be built out of other pointcuts with and, or, and
not (spelled <code class="literal">&&</code>, <code class="literal">||</code>,
and <code class="literal">!</code>). 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
<code class="function">setX</code> or a call to <code class="function">setY</code>.
</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 <code class="classname">FigureElement</code> 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 <code class="literal">pointcut</code> 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 <code class="literal">move()</code> 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"><em>name-based</em></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"><em>property-based</em></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 <code class="classname">Figure</code> whose the name begins with
"<code class="literal">make</code>" regardless of the method's parameters.
In our system, this picks out calls to the factory methods
<code class="function">makePoint</code> and <code class="function">makeLine</code>.
The pointcut
</p><pre class="programlisting">
call(public * Figure.* (..))
</pre><p>
picks out each call to <code class="classname">Figure</code>'s public
methods.
</p><p>
But wildcards aren't the only properties AspectJ supports.
Another pointcut, <code class="function">cflow</code>, 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 <code class="literal">move()</code>, 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"><div class="titlepage"><div><div><h3 class="title"><a name="advice"></a>Advice</h3></div></div></div><p>
So pointcuts pick out join points. But they don't
<span class="emphasis"><em>do</em></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"><em>Before
advice</em></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"><em>After advice</em></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:
<code class="literal">after returning</code>, <code class="literal">after
throwing</code>, and plain <code class="literal">after</code> (which runs
after returning <span class="emphasis"><em>or</em></span> throwing, like Java's
<code class="literal">finally</code>).
</p><pre class="programlisting">
after() returning: move() {
System.out.println("just successfully moved");
}
</pre><p>
<span class="emphasis"><em>Around advice</em></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"><div class="titlepage"><div><div><h4 class="title"><a name="idp68226800"></a>Exposing Context in Pointcuts</h4></div></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
<code class="literal">FigureElement</code> named fe, and two
<code class="literal">int</code>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
<code class="literal">this</code>, <code class="literal">target</code> and
<code class="literal">args</code> 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
<code class="function">setXY</code>: the target
<code class="classname">FigureElement</code> -- which it publishes as
<code class="literal">fe</code>, so it becomes the first argument to the
after advice -- and the two int arguments -- which it publishes
as <code class="literal">x</code> and <code class="literal">y</code>, 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 <code class="literal">x</code> and
<code class="literal">y</code> coordinates after each
<code class="classname">setXY</code> 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
<code class="literal">this</code>, <code class="literal">target</code> and
<code class="literal">args</code> 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"><div class="titlepage"><div><div><h3 class="title"><a name="inter-type-declarations"></a>Inter-type declarations</h3></div></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"><em>each affected class</em></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 <code class="classname">Screen</code> objects
observe changes to <code class="classname">Point</code> objects, where
<code class="classname">Point</code> is an existing class. We can implement
this by writing an aspect declaring that the class Point
<code class="classname">Point</code> has an instance field,
<code class="varname">observers</code>, that keeps track of the
<code class="classname">Screen</code> objects that are observing
<code class="classname">Point</code>s.
</p><pre class="programlisting">
aspect PointObserving {
private Vector Point.observers = new Vector();
...
}
</pre><p>
The <code class="literal">observers</code> field is private, so only
<code class="classname">PointObserving</code> can see it. So observers are
added or removed with the static methods
<code class="function">addObserver</code> and
<code class="function">removeObserver</code> 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
<code class="function">changes</code> 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 <code class="classname">Screen</code>'s nor
<code class="classname">Point</code>'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"><div class="titlepage"><div><div><h3 class="title"><a name="aspects"></a>Aspects</h3></div></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
<code class="literal">new</code> 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="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="starting.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="starting.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="starting-development.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 1. Getting Started with AspectJ </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Development Aspects</td></tr></table></div></body></html>
|