0% found this document useful (0 votes)
12 views

AspectJ程序设计指南

The document is a programming guide for AspectJ, an aspect-oriented programming extension for Java. It covers various aspects of AspectJ, including pointcuts, advice, and the integration of AOP concepts into Java programming. The guide is structured with sections and subsections detailing the functionalities and usage of AspectJ in software development.

Uploaded by

whk666888
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

AspectJ程序设计指南

The document is a programming guide for AspectJ, an aspect-oriented programming extension for Java. It covers various aspects of AspectJ, including pointcuts, advice, and the integration of AOP concepts into Java programming. The guide is structured with sections and subsections detailing the functionalities and usage of AspectJ in software development.

Uploaded by

whk666888
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 90

AspectJ

The AspectJTM Programming Guide

AspectJ

1
AspectJ

0 .............................................................................................................................................5
1 AspectJ ................................................................................................................................5
1.1. ...................................................................................................................................5
1.2. AspectJ .......................................................................................................................6
1.2.1 ...............................................................................................................7
1.2.2 ...................................................................................................................................7
1.2.3 ...................................................................................................................................8
1.2.4 ...................................................................................................................9
1.2.5 .......................................................................................................................9
1.2.6 .................................................................................................................................11
1.3. .............................................................................................................11
1.3.1 .........................................................................................................................11
1.3.2 .....................................................................................................12
1.3.3 .....................................................................................................13
1.3.4 .........................................................................................................................13
1.3.5 .........................................................................................................................14
1.4. .............................................................................................................14
1.4.1 .........................................................................................................................14
1.4.2 .....................................................................................................................15
1.4.3 .............................................................................................................16
1.5. .................................................................................................................................17
2 AspectJ ..............................................................................................................................17
2.1. .................................................................................................................................17
2.2. .................................................................................................................18
2.2.1 .............................................................................................................18
2.2.2 .................................................................................................................................18
2.2.3 .................................................................................................................................19
2.3. .................................................................................................................19
2.3.1 .............................................................................................................19
2.3.2 .....................................................................................................................21
2.3.3 .....................................................................................................................21
2.3.4 .....................................................................................................................23
2.3.5 HandleLiveness ...................................................................................................23
2.4. .................................................................................................................................24
2.5. .....................................................................................................................25
2.5.1 .....................................................................................................26
2.5.2 PointAssertions ...................................................................................................26
2.6. thisJoinPoint .............................................................................................................27
3 ...........................................................................................................................................28
3.1. .................................................................................................................................28
3.2. .............................................................................................28
3.3. .........................................................................................................................28

2
AspectJ

3.3.1 thisJoinPoint ........................................................................................29


3.3.2 .....................................................................................................................31
3.4. .............................................................................................................35
3.4.1 .....................................................................................................35
3.5. .............................................................................................................41
3.5.1 Bean ........................................................................................................................41
3.5.2 Subject-Observer .....................................................................................................44
3.5.3 .....................................................................................................47
3.6. .................................................................................................................53
3.6.1 .............................................................................................53
4 ...................................................................................................................................57
4.1. .................................................................................................................................57
5 ...........................................................................................................................................58
5.1. .................................................................................................................................58
5.2. .........................................................................................................................58
A AspectJ .............................................................................................................59
1. ....................................................................................................................................59
2. ............................................................................................................................60
3. ....................................................................................................................................61
4. ................................................................................................................62
4. ........................................................................................................................62
4. ....................................................................................................................................62
B AspectJ .....................................................................................................................63
1. ....................................................................................................................................63
2. ................................................................................................................................63
3. ....................................................................................................................................64
3.1. ...............................................................................................................................66
3.2. .......................................................................................................................66
3.3. ...............................................................................................................................67
3.4. .......................................................................................................................................69
3.5. .......................................................................................................................................70
3.6. ...............................................................................................................................71
4. ....................................................................................................................................72
4.1. .........................................................................................................................73
4.2. .................................................................................................................74
4.3. .....................................................................................................................74
4.4. .............................................................................................................75
5. ............................................................................................................................76
5.1. .................................................................................................................76
5.2. .........................................................................................................................77
5.3. .....................................................................................................................................77
5.4. .........................................................................................................................78
5.5. .....................................................................................................................78
5.6. .........................................................................................................................79

3
AspectJ

5.7. Softtened ......................................................................................................................79


5.8. .....................................................................................................................80
5.9. .............................................................................................................81
6. ....................................................................................................................................82
6.1. .........................................................................................................................82
6.2. .....................................................................................................................82
6.3. .........................................................................................................................84
C AspectJ .................................................................................................85
1. ....................................................................................................85
2. ........................................................................................................86
2.1. String+ .............................................................................................86
2.2. Handler .....................................................................................................86
2.3. .....................................................................................................87
................................................................................................................................................88
AspectJ ....................................................................................................................88
AspectJ For Jbuilder ................................................................................89

4
AspectJ

AspectJ

AOP
AspectJ

AspectJ
AspectJ

AspectJ AspectJ
AspectJ
AspectJ AspectJ

AspectJ AspectJ
AspectJ
AspectJ
AspectJ
AspectJ
AspectJ
AspectJ AspectJ

AspectJ AspectJ
AspectJ

1 AspectJ

1.1.

aspect-oriented programming (AOP)

AOP

AOP

AspectJ AspectJ Java

5
AspectJ

AspectJ
http://eclipse.org/aspectj AspectJ

AOP
AspectJ
Java

AspectJ
AspectJ
AspectJ
AOP

1.2. AspectJ

AspectJ AspectJ
AspectJ
FigureElements Points
Lines Figure Display

FigureEditor UML
AspectJ AOP

AOP

6
AspectJ

AspectJ
Java
Java Join Point Java
Java (pointcut) (Advice)
(Inter-type declaration) (Aspect)

AspectJ

AspectJ

AspectJ Java

AspectJ

1.2.1

AspectJ
(method call join points)
( )

1.2.2

AspectJ
call(void Point.setX(int))
void Point.setX(int) Point
void setX (||) (&&) (!)
call(void Point.setX(int)) || call(void Point.setY(int)) setX setY

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));

7
AspectJ

( )
FigureElement AspectJ

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));
move()

(name-based)
AspectJ
(property-based)
call(void Figure.make*(..)) Figure make
call(public * Figure.*(..)) Figure

AspectJ cflow
cflow(move()) move()
( 1.3.3)
move() (
)

1.2.3

( )
AspectJ
· (Before Advice)

before() : move(){ System.out.println(“ ”);}


· (After Advice)
Java
(after returning)
(after throwing) (after)
Java finally
after() returning : move(){
System.out.println(“ ”);
}
· (Around Advice)

8
AspectJ

1.2.4

after(FigureElement fe, int x, int y) returning:


...SomePointcut... {
...SomeBody...
}
fe FigureElement x,y

after(FigureElement fe, int x, int y) returning:


...SomePointcut... {
System.out.println(fe + " moved to (" + x + ", " + y + ")");
}
AspectJ
this target args

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 + ")");
}
FigureElement fe after
x y after setXY
x y

this target args

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 + ").");
}

1.2.5

AspectJ

9
AspectJ

Java

AspectJ

Screen Point Point


Point observers
Point Screen
aspect PointObserving {
private Vector Point.observers = new Vector();
...
}
observers PointObserving aspect
observers
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);
}
...
}
changes after

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());
}
}

10
AspectJ

static void updateObserver(Point p, Screen s) {


s.display(p);
}
}
Screen Point

1.2.6

Java

abstract AspectJ
new
aspectOf()

aspect Logging {
OutputStream logStream = System.err;

before(): move() {
logStream.println("about to move");
}
}

1.3.

AspectJ

Java

AspectJ

1.3.1

aspect SimpleTracing {
pointcut tracedCall():
call(void FigureElement.draw(GraphicsContext));

before(): tracedCall() {

11
AspectJ

System.out.println("Entering: " + thisJoinPoint);


}
}
thisJoinPoint
FigureElement draw
Entering: call(void FigureElement.draw(GraphicsContext))
AspectJ AspectJ
tracedCall
(
)

AspectJ

AspectJ
AspectJ

1.3.2

Line rotate
Line rotate rotate Point set*
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++;
}
}
( )
Line rotate
rotate Point set

12
AspectJ

1.3.3

Bertand Meyer

( )
AspectJ
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.");
}
}
( )
setX Point x setX
setXY setX setX
setX setXY

AspectJ

1.3.4

FigureElement
FigureElement
static aspect RegistrationProtection {
pointcut register(): call(void Registry.register(FigureElement));
pointcut canRegister(): withincode(static * FigureElement.make*(..));

13
AspectJ

before(): register() && !canRegister() {


throw new IllegalAccessException("Illegal call " + thisJoinPoint);
}
}
withincode FigureElement ( make
)
( ) before
register
AspectJ declare error

static aspect RegistrationProtection {

pointcut register(): call(void Registry.register(FigureElement));


pointcut canRegister(): withincode(static * FigureElement.make*(..));

declare error: register() && !canRegister(): "Illegal call"


}

withincode

1.3.5

AspectJ make-file

make-file
Java make AspectJ
Java

1.4.

AspectJ

1.4.1

14
AspectJ

testAndClear
move After
move
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;
}
}
AspectJ Java
testAndClear setFlag
setFlag

·
·
·
·

1.4.2

Java

AspectJ after
ColorControllingClient

15
AspectJ

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));
}
}
AOP

1.4.3

com.bigboxco PublicMethodCall
after

aspect PublicErrorLogging {
Log log = new Log();

pointcut publicMethodCall():
call(public * com.bigboxco.*.*(..));

after() throwing (Error e): publicMethodCall() {


log.write(e);
}
}
com.bigboxco
cflow

after() throwing (Error e):


publicMethodCall() && !cflow(publicMethodCall()) {
log.write(e);
}
AspectJ JavaParser 35

parseMethodDec parseThrows parseExpr

16
AspectJ

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;
}
}

call(* JavaParser.parse*(..))
!call(Stmt parseVarDec(boolean)) parseVarDec
Java parse*
parse* ASTObject

1.5.

AspectJ Java
AspectJ Java
AspectJ
AspectJ

AspectJ
Java
AspectJ
AspectJ

2 AspectJ

2.1.

AspectJ AspectJ

17
AspectJ

2.2.

2.2.1

AspectJ
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 }
FaultHandler Server 3 (5-7 9-11
) 13 15-17 19-22

before after around

2.2.2

AspectJ

13
pointcut services(Server s): target(s) && call(public * *(..))
services Server
services Server
FaultHandler

18
AspectJ

server

Server
services
Server (target(s))
call (call(..)) (&&, and) (calls)
(*)
(*) (..); public

Java

2.2.3

15-17
{
if (s.disabled) throw new DisabledException();
}
Server 19-22
(services)
{
s.disabled = true;
reportFault();
}
FaultException after

2.3.

2.3.1

Java
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; }

19
AspectJ

int getX() { return x; }


int getY() { return y; }
}
AspectJ Java
Point
void setX(int x) { this.x = x; }
Point setX
{ this.x=x;} Point
{this.x=x;this.y=y;}

Java
Java

pointcut setter(): target(Point) &&


(call(void setX(int)) ||
call(void setY(int)));
Point setX int setY int

pointcut ioHandler(): within(MyClass) && handler(IOException);


MyClass

execution(void Point.setX(int))

call(void Point.setX(int))

handler(ArrayOutOfBoundsException)
SomeType
this(SomeType)
SomeType
target(SomeType)
Test main
cflow(call(void Test.main())
(“||”) (“and”) (“!”)
·
1 execution(* *(..))
2 call(* set(..))
1 2 set

·
1 execution(int *())

20
AspectJ

2 call(* setY(long))
3 call(* Point.setY(int))
4 call(*.new(int,int))
1 int 2 long
setY 3 Point int setY
4 int
·
1 target(Point) && call(int *())
2 call(* *(..)) && (within(Line) || within(Point))
3 within(*) && execution(*.new(int))
4 !this(Point) && call(int *(..))
1 Point int 2 Line Point
3 int 4
int Point
·
1 call(public * *(..))
2 execution(!static * *(..))
3 execution(public !static * *(..))
1 2 3

·
interface MyInterface { … }
call(* MyInterface.*(..)) MyInterface

2.3.2

(call)
(execution)
AspectJ call execution call execution

call execution
call
( )
execution call

2.3.3

&& ||
cflow cflowbelow
cflow p p P

21
AspectJ

P ---------------------
\
\ cflow of P
\
cflow(P) && cflow(Q) P Q
P ---------------------
\
\ cflow of P
\
\
\
Q ------------\-------
\ \
\ cflow of Q \ cflow(P) && cflow(Q)
\ \
P Q
cflow(P && Q) P Q
P && Q -------------------
\
\ cflow of (P && Q)
\
P Q P&&Q

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");
}

22
AspectJ

before(): cflow(fooPC() && gooPC()) && printPC() && !within(A) {


System.out.println("should not occur");
}
}

2.3.4

pointcut setter(): target(Point) &&


(call(void setX(int)) ||
call(void setY(int)));
Point setX(int) setY(int) setter

pointcut setter(Point p): target(p) &&


(call(void setX(int)) ||
call(void setY(int)));
Point
Point
setter
pointcut setter(Point p, int newval): target(p) && args(newval)
&& (call(void setX(int)) || call(void setY(int)));
Point int Point
int

pointcut badPointcut(Point p1, Point p2):


(target(p1) && call(void setX(int))) ||
(target(p2) && call(void setY(int)));
p1 setX p2 setY
p1 p2

2.3.5 HandleLiveness

Handle Partner
HandleLiveness Partner

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();

23
AspectJ

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 {}

2.4.

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);
}

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);
}

before
before(Point p, int x): target(p) && args(x) && call(void setX(int)) {
if (!p.assertX(x)) return;
}
after

24
AspectJ

after(Point p, int x): target(p) && args(x) && call(void setX(int)) {


if (!p.assertX(x)) throw new PostConditionViolation();
}
after
after(Point p) returning(int x): target(p) && call(int getX()) {
System.out.println("Returning int value " + x + " for p = " + p);
}
after
after() throwing(Exception e): target(Point) && call(void setX(int)) {
System.out.println(e);
}
around
proceed
void around(Point p, int x): target(p)
&& args(x)
&& call(void setX(int)) {
if (p.assertX(x)) proceed(p, x);
p.releaseResources();
}

2.5.

Server disabled boolean false


private boolean Server.disabled=false;
Server
disabled Server
disabled

Point getX x
public int Point.getX(){ return this.x;}
this Point
Point.getX()

Point
public Point.new(int x,int y){ this.x=x;this.y=y; }

public int Point.x=0;


Point x 0
x

25
AspectJ

Point Comparable
declare parents : Point implement Comparable;
Point

Point GeometricObject
declare parents : Point extends GeometricObject;

Public String Point.name;


Public void Point.setName(String name){ this.name=name; }

aspect A {
private interface HasName {}
declare parents: (Point || Line || Square) implements HasName;

private String HasName.name;


public String HasName.getName() { return name; }
}
HasName Point Line Square
name getName

2.5.1

AspectJ aspect

private int Foo.x;


Foo x

int Foo.x;

2.5.2 PointAssertions

Point assertion assertX


assertY setX setY

class Point {
int x, y;
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }

26
AspectJ

public static void main(String[] args) {


Point p = new Point();
p.setX(3);
p.setY(333);// Y
}
}

aspect PointAssertions {
// X Y 0 100
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)) { // 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)) { // Y
System.out.println("Illegal value for y"); return;
}
}
}

2.6. thisJoinPoint

AspectJ thisJoinPoint
ThisJoinPoint this
thisJoinPoint org.aspectj.lang.JoinPoint
Java thisJoinPoint
toString()
class TraceNonStaticMethods {
before(Point p): target(p) && call(* *(..)) {
System.out.println("Entering " + thisJoinPoint + " in " + p);
}
}
thisJoinPoint
thisJoinPoint.getArgs();

thisJoinPoint.getStaticPart();

27
AspectJ

thisJoinPointStaticPart thisJoinPoint

thisJoinPointStaticPart == thisJoinPoint.getStaticPart()
thisJoinPoint.getKind() == thisJoinPointStaticPart.getKind()
thisJoinPoint.getSignature() == thisJoinPointStaticPart.getSignature()
thisJoinPoint.getSourceLocation() == thisJoinPointStaticPart.getSourceLocation()
thisEnclosingJoinPointStaticPart thisJoinPointStaticPart

before() : execution (* *(..)) {


System.err.println(thisEnclosingJoinPointStaticPart.getSourceLocation())
}

3.1.

AspectJ
AspectJ
AspectJ
AspectJ

3.2.

AspectJ http://eclipse.org/aspectj

AspectJ examples
.lst arglist ajc

ajc -argfile telecom/billing.lst


classpath AspectJ aspectjrt.jar
classpath Java -classpath
(In Unix use a : in the CLASSPATH)
java -classpath ".:InstallDir/lib/aspectjrt.jar" telecom.billingSimulation
(In Windows use a ; in the CLASSPATH)
java -classpath ".;InstallDir/lib/aspectjrt.jar" telecom.billingSimulation

3.3.

AspectJ

28
AspectJ

(Join Points and thisjoinPoint)


(Roles and Views)

3.3.1 thisJoinPoint

AspectJ examples/tjp

( ) ( )

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;
}
}

pointcut execsInProblemClass(): within(ProblemClass)


&& execution(* *(..));
ProblemClass

thisJoinPoint thisJoinPoint
org.aspectj.lang.JoinPoint

( )

thisJoinPointStaticPart

tjp.Demo tjp/Demo.java
foo bar go main
public class Demo {
static Demo d;

public static void main(String[] args){


new Demo().go();

29
AspectJ

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 + ")";
}
}
GetInfo Demo around Demo foo bar
thisJoinPoint
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();

30
AspectJ

for (int i = 0; i < args.length; i++) {


println(" " + i + ". " + names[i] +
":"+ types[i].getName() +
"="+ args[i]);
}
}
}
goCut
cflow(this(Demo)) && execution(void go())
Demo.go go around
!execution(* go()) go
thisJoinPoint
thisJoinPointStaticPart getSignature() org.aspectj.lang.Signature
org.aspectj.lang.reflect.CodeSignature

3.3.2

AspectJ examples/introduction

AspectJ

Point Point Point


AspectJ
Point

Point

Point UML

31
AspectJ

CloneablePoint Cloneable
declare parents:

Point implements Cloneable;


Point clone() Java Object
clone() Cloneable
Cloneable clone()
Point Point
Object.clone()
main()
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) {}

32
AspectJ

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 );
}
}

ComparablePoint Point Comparable


compareTo()

declare parents:

Point implements Comparable;


public Point.compareTo() p1 p2 Point

main()
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);

33
AspectJ

System.out.println("p1 =?= p2 :" + p1.compareTo(p2));

p1.offset(1,1);
System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
}
}

HashablePoint Point equals() hashCode()

Java hashCode() HashTable (key)

equals() Object.equals() true


Point equals() hashCode()
x y rho thrta
Point equals() hashCode()
HashablePoint Point equals() hashCode() Point
x y get

main()
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());

34
AspectJ

System.out.println("p2.hashCode() = " + p2.hashCode());

h.put(p1, "P1");
System.out.println("Got: " + h.get(p2));
}
}

3.4.

3.4.1

AspectJ examples/tracing

AspectJ

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) + ") ");
}
}
TwoDShape Square Circle
public class Circle extends TwoDShape {
protected double r;

35
AspectJ

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());
}
}

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());
}
}
Java AspectJ AspectJ
examples
ajc -argfile tracing/notrace.lst

java tracing.ExampleMain
classpath Java

c1.perimeter() = 12.566370614359172
c1.area() = 12.566370614359172

36
AspectJ

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)

1
Trace
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) {...}
}
AspectJ
traceEntry traceExit TRACELEVEL PrintStream 40

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());
}
}

before after thisJoinPointStaticPart

ajc -argfile tracing/tracev1.lst

tracing.version1.TraceMyClasses

37
AspectJ

--> 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()

38
AspectJ

<-- String tracing.TwoDShape.toString()


<-- String tracing.Square.toString()
s1.toString(): Square side = 1.0 @ (1.0, 2.0)
TraceMyClasses ajc

TraceMyClasses—version1
Trace—version1
version2/Trace.java
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();
}
version2/TraceMyClasses.java
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);
}
}

examples
ajc -argfile tracing/tracev2.lst
tracev2.lst Trace.java TraceMyClasses.java
tracing.version2.TraceMyClasses main version 1

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;
}

39
AspectJ

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());
}
}

40
AspectJ

1 Trace
1

traceEntry traceExit public


protected

3.5.

3.5.1 Bean

AspectJ InstallDir/examples/bean
Java Bean Point
Java Bean Bean
Bean Serializable
Externalizable Bean set
get getproperty setproperty property Bean Bean

setproperty
Point Point bean
x y set Bound
Point get set
getters setters

class Point {

protected int x = 0;
protected int y = 0;

public int getX() {


return x;
}

public int getY() {


return y;
}

41
AspectJ

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() + ")" ;
}
}
Point BoundPoint
Point support PropertyChangeSupport
private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
bean
Point this support

Point

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);

42
AspectJ

}
public void Point.hasListeners(String propertyName) {
support.hasListeners(propertyName);
}
Point 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));
}
}

point set offset point


point
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());

43
AspectJ

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);
}
...
}
examples
ajc -argfile bean/files.lst
java bean.Demo

3.5.2 Subject-Observer

AspectJ InstallDir/examples/ observer


Subject/Observer

Subject/Observer
Observers Subjects
Subject/Observer

Subject Observer SubjectObserverProtocol


Subject Observer Observer

interface Subject {
void addObserver(Observer obs);
void removeObserver(Observer obs);
Vector getObservers();
Object getData();
}
Observer Subject set get Subject
update

interface Observer {
void setSubject(Subject s);

44
AspectJ

Subject getSubject();
void update();
}
SubjectObserverProtocol Subject
Observer update
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; }

Observer Subject
Button java.awt.Button click()
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);

45
AspectJ

setBackground(defaultBackgroundColor);
setForeground(defaultForegroundColor);
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Button.this.click();
}
});
display.addToFrame(this);
}

public void click() {}

}
Subject
ColorLabel colorCycle() Observer
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);
}
}
SubjectObserverProtocolImpl subject/observer Button Subject
ColoeLabel Observer
package observer;

import java.util.Vector;

aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol {

declare parents: Button implements Subject;


public Object Button.getData() { return this; }

46
AspectJ

declare parents: ColorLabel implements Observer;


public void ColorLabel.update() {
colorCycle();
}

pointcut stateChanges(Subject s):


target(s) &&
call(void Button.click());

}
Button ColorLabel
stateChanges Button ColorLabel button

Demo
subjects observers

ajc -argfile observer/files.lst


java observer.Demo

3.5.3

AspectJ InstallDir/examples/ telecom

builling timing Timing

basic timing billing BasicSimulation,


TimingSimulation BillingSimulation AbstractSimulation

Basic Object
Customer Call Connection Connection
Local LongDistance Customer name areaCode call
Connection

47
AspectJ

Customer call pickup hangup merge merge Call


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;
}

48
AspectJ

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);
}
}
Call call
Local LongDistance
call
Connection PENDING
COMPLETED DROPPED
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;
}

49
AspectJ

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);
}

class Local extends Connection {


Local(Customer a, Customer b) {
super(a, b);
System.out.println("[new local connection from " +
a + " to " + b + "]");
}
}
class LongDistance extends Connection {
LongDistance(Customer a, Customer b) {
super(a, b);
System.out.println("[new long distance connection from " +
a + " to " + b + "]");
}
}

ajc -argfile telecom/basic.lst


java telecom.BasicSimulation
Timing

Timer
TimeLog

class Timer {

50
AspectJ

long startTime, stopTime;

public void start() {


startTime = System.currentTimeMillis();
stopTime = startTime;
}

public void stop() {


stopTime = System.currentTimeMillis();
}

public long getTime() {


return stopTime - startTime;
}
}
Timing Customer totalConnectTime
Connection Timer
public long Customer.totalConnectTime = 0;
private Timer Connection.timer = new Timer();
timer
endTiming Billing

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();
}

51
AspectJ

}
Billing Timing
Billing Connection payer
Connection callRate
Timer Timing.endTiming
Billing Timing Timing
Customer totalCharge
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;
}
}
Timing Billing

private

52
AspectJ

TimingSimulation.java report(Customer)
AbstractSimulation Customer Timing

protected void report(Customer c){


Timing t = Timing.aspectOf();
System.out.println(c + " spent " + t.getTotalConnectTime(c));
}
timing.lst billing.lst timing billing timing

ajc -argfile telecom/timing.lst


java telecom.TimingSimulation
timng billing
ajc -argfile telecom/billing.lst
java telecom.BillingSimulation

Timing Billing
Billing Timing Billing Timing

Billing Timing.endTiming
Billing timer

3.6.

3.6.1

InstallDir/examples/tracing
3
traceEntry tracExit

AspectJ

traceEntry traceExit
public static void traceEntry(String str);
public static void traceExit(String str);

Trace.traceEntry("Square.distance in " + toString());

public static void traceEntry(String str, Object obj);


public static void traceExit(String str, Object obj);

53
AspectJ

Trace.traceEntry("Square.distance", this);

traceEntry traceExit
2 traceEntry
traceExit Trace
Trace
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);

54
AspectJ

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);
}
}
traceEntry traceExit
examples/tracing/version3 Trace

methods toString toString

&& !cflow(execution(String toString()))


toString

ajc -argfile tracing/tracev3.lst


java tracing.version3.TraceMyClasses

--> 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)

55
AspectJ

--> 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)

56
AspectJ

4.1.

AspectJ
/* 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 */


sqlAcess
pointcut illegalSource():
within(com.foo..*) && !within(com.foo.sqlAccess.*);

declare error: restrictedCall() && illegalSource():


"java.sql package can only be accessed from com.foo.sqlAccess";

AbstractFacade
pointcut nonAbstract(AbstractFacade af):
call(* *(..))
&& target(af)
&& !if(af.getClass() == AbstractFacade.class);

AbstractFacade

pointcut nonAbstract(AbstractFacade af):


call(* *(..))
&& target(af);

AbstractFacade AbstractFacade
pointcut callToUndefinedMethod():
call(* AbstractFacade+.*(..))
&& !call(* AbstractFacade.*(..));

AbstractFacade AbstractFacade
pointcut executionOfUndefinedMethod():
execution(* *(..))
&& within(AbstractFacade+)
&& !within(AbstractFacade)

57
AspectJ

5.1.

AspectJ

5.2.

Java
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();
}
}
}
println
Java StackOverflowExceptions
finally finally JVM

aspect A {
before(): call(* *(..)) { System.out.println("before"); }
after(): call(* *(..)) { System.out.println("after"); }
}
println call(* *(..))
after
aspect A {
before(): call(* *(..)) { System.out.println("before"); }
after() returning: call(* *(..)) { System.out.println("after"); }
}
StackOverflowException
within
aspect A {

58
AspectJ

before(): call(* *(..)) && !within(A) { System.out.println("before"); }


after() returning: call(* *(..)) && !within(A) { System.out.println("after"); }
}

aspect A {
before(): call(* MyObject.*(..)) { System.out.println("before"); }
after() returning: call(* MyObject.*(..)) { System.out.println("after"); }
}

A AspectJ

1.

call(Signature)
Signature
execution(Signature)
Signature

get(Signature)
Signature
set(Signature)

handler(TypePattern)

adviceexecution()

staticinitialization(TypePattern)
TypePattern
initialization(Signature)
TypePattern

preinitialization(Signature)

59
AspectJ

TypePattern

within(TypePattern)
TypePattern
withincode(Signature)
TypePattern

Instanceof
this(Type or Id)
Type or Id
target(Type or Id)
Type or Id
args(Type or Id, ...)
Type or Id

cflow(Pointcut)
Pointcut P P
cflowbelow(Pointcut)
Pointcut P P

if(Expression)
Expression

! Pointcut
Pointcut
Pointcut0 && Pointcut1
Pointcut0 Pointcut1
Pointcut0 || Pointcut1
Pointcut0 Pointcut1
( Pointcut )
Pointcut

2.

TypeNamePattern
Name
SubtypePattern

ArrayTypePattern

60
AspectJ

[]
!TypePattern
not
TypePattern0 && TypePattern1
TypePattern0 TypePattern1
TypePattern0 || TypePattern1
TypePattern0 TypePattern1
( TypePattern )
TypePattern

TypeNamePattern * * ..

* .
.. .

3.

[ strictfp ] AdviceSpec [ throws TypeList ] : Pointcut { Body }


AdviceSpec
before( Formals )

after( Formals ) returning [ ( Formal ) ]


Formal
after( Formals ) throwing [ ( Formal ) ]
Throwable Formal
Formal Formal Throwable
after( Formals )

Type around( Formals )


around

thisJoinPoint
org.aspectj.lang.JoinPoint
thisJoinPointStaticPart
thisJoinPoint.getStaticPart()
thisEnclosingJoinPointStaticPart

61
AspectJ

4.

Modifiers ReturnType OnType . Id ( Formals ) [ throws TypeList ] { Body }


OnType
abstract Modifiers ReturnType OnType . Id ( Formals ) [ throws TypeList ] ;
OnType
Modifiers OnType . new ( Formals ) [ throws TypeList ] { Body }
OnType
Modifiers Type OnType . Id [ = Expression ] ;
OnType

4.

declare parents : TypePattern extends Type ;


TypePattern Type
declare parents : TypePattern implements TypeList ;
TypePattern TypeList
declare warning : Pointcut : String ;
String Pointcut
declare error : Pointcut : String ;
String Pointcut
declare soft : Type : Pointcut ;
Pointcut org.aspectj.lang.SoftException
declare precedence : TypePatternList ;
TypePatternList

4.

[ privileged ] Modifiers aspect Id [ extends Type ] [ implements TypeList ] [ PerClause ] { Body }

PerClause issingleton

62
AspectJ

PerClause
[ issingleton ] aspectOf()
perthis(Pointcut)
Pointcut aspectOf(Object)
pertarget(Pointcut)
Object Pointcut aspectOf(Object)

percflow(Pointcut) Pointcut cflow(Pointcut)


aspectOf()
percflowbelow(Pointcut) Pointcut cflowbelow(Pointcut)
aspectOf()

B AspectJ

1.

AspectJ Java

pointcut
before after around

declare

Java
aspect

2.

AspectJ

AspectJ
Method call

Method execution

Constructor call
super this

63
AspectJ

after returning
Constructor execution
this super
this

void
Static initializer execution

void
Object pre-initialization

this() super()
void
Object initialization

this
void
Field reference

(static final )
Java
Field set
void
(static final )
Java
Handler execution
void
Advice execution

3.

AspectJ

call(MethodPattern)
MethodPattern
execution(MethodPattern)
MethodPattern
get(FieldPattern)
FieldPattern
set(FieldPattern)
FieldPattern

64
AspectJ

call(ConstructorPattern)
ConstructorPattern
execution(ConstructorPattern)
ConstructorPattern
initialization(ConstructorPattern)
ConstructorPattern
preinitialization(ConstructorPattern)
ConstructorPattern
staticinitialization(TypePattern)
TypePattern
handler(TypePattern)
TypePattern
adviceexecution()

within(TypePattern)
TypePattern
withincode(MethodPattern)
MethodPattern
withincode(ConstructorPattern)
ConstructorPattern
cflow(Pointcut)
pointcut p p
cflowbelow(Pointcut)
pointcut p p
this(Type or Id)
this Type Id
target(Type or Id)
Type
Id

args(Type or Id, ...)

PointcutId(TypePattern or Id, ...)


PointcutId
if(BooleanExpression)
BooleanExpression
thisJoinPoint

! Pointcut
Pointcut
Pointcut0 && Pointcut1
Pointcut0 Pointcut1
Pointcut0 || Pointcut1
Pointcut0 Pointcut1

65
AspectJ

( Pointcut )
Pointcut

3.1.

pointcut
pointcut publicIntCall(int i):
call(public * *(int)) && args(i);

public private
class C {
pointcut publicCall(int i):
call(public * *(int)) && args(i);
}

class D {
pointcut myPublicCall(int i):
C.publicCall(i) && within(SomeType);
}
final abstract

abstract aspect A {
abstract pointcut publicCall(int i);
}

aspect B extends A {
pointcut publicCall(int i): call(public Foo.m(int)) && args(i);
}
final
override
overload

aspect B percflow(publicCall()) {
pointcut publicCall(): call(public Foo.m(int));
}

3.2.

PublicIntCall
Java

Java

66
AspectJ

this target args


pointcut intArg(int i): args(i);
int

pointcut publicCall(int x): call(public *.*(int)) && intArg(x);


pointcut intArg(int i): args(i);
int

pointcut publicCall(): call(public *.*(..)) && args(Object);


Object
pointcut publicCall(Object o): call(public *.*(..)) && args(o);
int
java.lang.Interger

3.3.

AspectJ
call(MethodPattern)
execution(MethodPattern)

( )
AspectJ
get(FieldPattern)
set(FieldPattern)

args T int x

aspect GuardedX {
static final int MAX_CHANGE = 100;
before(int newval): set(int T.x) && args(newval) {
if (Math.abs(newval - T.x) > MAX_CHANGE)
throw new RuntimeException();
}
}

AspectJ
call(ConstructorPattern)
execution(ConstructorPattern)
initialization(ConstructorPattern)
preinitialization(ConstructorPattern)

67
AspectJ

AspectJ
staticinitialization(TypePattern)

AspectJ
handler(TypePattern)

args FooException

aspect NormalizeFooException {
before(FooException e): handler(FooException) && args(e) {
e.normalize();
}
}

AspectJ
adviceexecution()

aspect TraceStuff {
pointcut myAdvice(): adviceexecution() && within(TraceStuff);

before(): call(* *(..)) && !cflow(myAdvice) {


// do something
}
}

AspectJ

this(Type or Id)
target(Type or Id)
this this target
target

args(Type or Id or "..", ...)


args

1
2

68
AspectJ

3 *
4 ..

args(int, .., String) int


String

cflow(Pointcut)
cflowbelow(Pointcut)
cflow Pointcut P P
Pointcut
cflowbelow Pointcut P P
Pointcut

AspectJ

within(TypePattern)
withincode(MethodPattern)
withincode(ConstructorPattern)
within TypePattern

withincode

if(BooleanExpression)

thisJoinPoint
if(thisJoinPoint.getKind().equals("call"))

3.4.

((Integer)i).toString() ((Object)i).toString()

69
AspectJ

void
around

3.5.

withincode, call, execution, get, set

AspectJ Java

call(public final void C.foo() throws ArrayOutOfBoundsException)


call(public final void *.*() throws ArrayOutOfBoundsException)

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*);

ThrowsClausePattern ThrowsClausePatternItems
ThrowsClausePatternItem :
[ ! ] TypeNamePattern

70
AspectJ

ThrowsClausePattern ThrowsClausePatternItem
item
ThrowsClausePatternItem
ThrowsClausePattern

• call(* *(..) throws !IOException)


• call(* *(..) throws (!IOException))

void m() throws RuntimeException, IOException {}


[1] m m IOException
[2] m m

3.6.

Object java.lang.util.HashMap Map.Entry int


* *
call(void foo(*))
void foo
* .. * .
handler(java.util.*Map)
java.util java.util.Map.Entry
..
within(com.xerox..*)
com.xerox

call(Foo.new())
Foo
call(Foo+.new())
Foo Foo

call(*Handler+.new())

Object[] com.Xerox..*[][] Object+[]


&& || !
staticinitialization(Foo || Bar)
Foo Bar

71
AspectJ

call((Foo+ && ! Foo).new(..))


Foo

4.

[ strictfp ] AdviceSpec [ throws TypeList ] : Pointcut { Body }


AdviceSpec
before( Formals )
after( Formals ) returning [ ( Formal ) ]
after( Formals ) throwing [ ( Formal ) ]
after( Formals )
Type around( Formals )

AspectJ AspectJ

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");
}
}
After returning
after() returning: call(public Object *(..)) {
System.out.println("Returned normally");
}
After returning instanceof

Java byte short int


float boolean boolean instanceof

Object
int java.lang.Integer
null

72
AspectJ

null T T

Around
void
around
around
aspect A {
int around(): call(int C.foo()) {
return 3;
}
}
around
proceed( ... )
proceed around

aspect A {
int around(int i): call(int C.foo(Object, int)) && args(i) {
int newi = proceed(i*2)
return newi/2;
}
}
around Object
A
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);
}
}

aspect A {
after() returning (int i): call(int C.foo()) {
i = i * 2;
}
}

around

4.1.

strictfp float

73
AspectJ

4.2.

throws

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();
}
}

FileNotFoundException
AspectJ
method call and execution
throws
constructor call and execution
throws
field get and set

exception handler execution

static initializer execution

pre-initialization and initialization


throws
advice execution
throws

4.3.

74
AspectJ

[1] A B declare precedence A


B
[2] A B A B
declare precedence
[3]

[1] after
[2]

aspect A {
before(): execution(void main(String[] args)) {}
after(): execution(void main(String[] args)) {}
before(): execution(void main(String[] args)) {}
}

around proceed around


before

after returning
after throwing
after

4.4.

thisJoinPoint, thisJoinPointStaticPart,
thisEnclosingJoinPointStaticPart

pointcut publicCall(): call(public * *(..));


ThisJoinPoint
ThisJoinPointStaticPart
thisJoinPoint.getStaticPart()
ThisEnclosingJoinPointStaticPart

Java java.lang.reflect AspectJ


ThisJoinPoint org.aspectj.lang.ThisJoinPoint
thisStaticJoinPoint org.aspectj.lang.JoinPoint.StaticPart

75
AspectJ

5.

AspectJ declare

5.1.

AspectJ

[ Modifiers ] Type OnType . Id(Formals) [ ThrowsClause ] { Body }


abstract [ Modifiers ] Type OnType . Id(Formals) [ ThrowsClause ] ;
OnType OnType
public abstract AspectJ
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();
}
}

[ Modifiers ] OnType . new ( Formals ) [ ThrowsClause ] { Body }


OnType
OnType final
OnType
Java
supper()

[ Modifiers ] Type OnType . Id = Expression;


[ Modifiers ] Type OnType . Id;
OnType OnType
public static final

This
OnType Java static
this

76
AspectJ

5.2.

public private protected


AspectJ protected
private

private private Private


private Java
void writeObject(ObjectOutputStream) java.io.Serializable private

5.3.

otherPakage
A
aspect A {
private Registry otherPackage.*.r;
public void otherPackage.*.register(Registry r) {
r.register(this);
this.r = r;
}
}
otherPackage r A
otherPackage register
otherPackage private package-protected r
otherPackage r otherPackage
public r this.r = r private r
public r
otherPackage register(Register)
register
Java
A subclass can inherit multiple fields from its superclasses, all with the same name and type.
However, it is an error to have an ambiguous reference to a field.

A subclass can only inherit multiple methods 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).

77
AspectJ

declare
precedence

5.4.

declare parents

aspect A {
declare parents: SomeClass implements Runnable;
public void SomeClass.run() { ... }
}
Runnable void run()
Runnable Runnable run
public

5.5.

public static fianl public abstract

static

{Object, C, D, E} {M, N, O, P, Q}

Object M O
\/\/
C N Q
\/ /
D P
\/

E
Object M C O N D Q P E

78
AspectJ

5.6.

AspectJ
declare error: Pointcut: String;
declare warning: Pointcut: String;
String

5.7. Softtened

Java
static org.aspectj.lang.SoftException
RuntimeException RuntimeException
aspect A {
declare soft: Exception: execution(void main(String[] args));
}

org.aspectj.lang.SoftException
aspect A {
void around() execution(void main(String[] args)) {
try { proceed(); }
catch (Exception e) {
throw new org.aspectj.lang.SoftException(e);
}
}
}
Java
declare soft

abstract aspect A {
abstract pointcut softeningPC();

before() : softeningPC() {
Class.forName("FooClass"); // error: uncaught ClassNotFoundException
}

declare soft : ClassNotFoundException : call(* Class.*(..));


}

79
AspectJ

5.8.

declare precedence : TypePatternList ;


TypePatternList

TypePatternList

declare precedence: *..*Security*, Logging+, *;

(1) Security
(2) Loggin ( )
non-securuty

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++;
}
}
CountEntry args
DisallowNulls
Ordering CountEntry DisallowNulls

declare precedence: A, B, A ; // error

declare precedence: B, A;
declare precedence: A, B;
A B
A B

abstract aspect Logging {

80
AspectJ

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);
}

declare precedence: Logging, Profiling; Logging Profiling;


declare precedence: MyLogging, MyProfiling;
declare precedence: Logging+, Profiling+;

5.9.

declare

cflow
cflowbelow
this
target
args
if

81
AspectJ

6.

aspect aspect class


aspect new

static

6.1.

new

6.2.

new

singleton
aspect Id { ... }
aspect Id issingleton { ... }
issingleton
aspectOf()
A.asoectOf() A classfile

82
AspectJ

Per-object
aspect Id perthis(Pointcut) { ... }
aspect Id pertarget(Pointcut) { ... }
A perthis(Pointcut) A Pointcut
A
A

A pertarget(Pointcut) A
Pointcut A
A
A.aspectOf(Object) Object A
Pointcu A

perthis pertarget AspectJ

Per-control-flow
aspect Id percflow(Pointcut) { ... }
aspect Id percflowbelow(Pointcut) { ... }
A percflow(Pointcut) percflowbelow(Pointcut) A
Pointcut
A
A.aspectOf() A

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");
}

83
AspectJ

}
Watchcall
Watchcall Watchcal

6.3.

privileged aspect Id { ... }


Java
package-protected

private protected privileged


private
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();
}
}
A privileged c.i
privileged
privileged
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);
}
}
private 999 C private A
privileged
privileged private

84
AspectJ

C AspectJ

1.

AspectJ AspectJ
JVM

before(): get(int Point.x) { System.out.println("got x"); }


Point int x

AspectJ

AspectJ ajc ajc


new Point().x
AspectJ Java Client.java
Client.class native
ajc
ajc caller
ajc
ajc Handler
ajc Handler after around ,
ajc around

AspectJ perthis pertarget


perthis
Object perthis(Object) Object
pertarget
declare parents

declare parents : String implements MyInterface


java.lang.String java.lang.String

ajc
static
AspectJ
ajc

85
AspectJ

2.

2.1. String+

Java Foo.class Class.forName


ClassNotFoundException
Java + String StringBuffer.append
AspectJ

AspectJ
class Test {
void main(String[] args) {
System.out.println(Test.class); // calls Class.forName
System.out.println(args[0] + args[1]); // calls StringBuffer.append
}
}

2.2. Handler

Handler AspectJ Handler

After and around advice cannot apply to handler join points.


The control flow of a handler join point cannot be detected.

After around handler


handler

after returning throwing finally hangdler


AspectJ Before
Handler
cflow(call(void foo()) || handler(java.io.IOException))
cflow(call(void foo())) cflow(handler(Type))

before handler
before(): handler(java.io.IOException) && cflow(void parse()) {
System.out.println("about to handle an exception while parsing");
}

AspectJ AspectJ 1.0.6 handler

86
AspectJ

2.3.

Java
class C {
double d = Math.sqrt(2);
}
AspectJ

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
}

this

87
AspectJ

AspectJ Java
AspectJ Java
AspectJ
AspectJ

AspectJ
Java
AspectJ
AspectJ

88
AspectJ

89
AspectJ

90

You might also like