AspectJ程序设计指南
AspectJ程序设计指南
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
AspectJ
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.
AOP
AOP
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)
8
AspectJ
1.2.4
1.2.5
AspectJ
9
AspectJ
Java
AspectJ
aspect PointObserving {
private Vector Point.observers = new Vector();
10
AspectJ
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
AspectJ
AspectJ
AspectJ
1.3.2
Line rotate
Line rotate rotate Point set*
aspect SetsInRotateCounting {
int rotateCount = 0;
int setCount = 0;
12
AspectJ
1.3.3
Bertand Meyer
( )
AspectJ
aspect PointBoundsChecking {
AspectJ
1.3.4
FigureElement
FigureElement
static aspect RegistrationProtection {
pointcut register(): call(void Registry.register(FigureElement));
pointcut canRegister(): withincode(static * FigureElement.make*(..));
13
AspectJ
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;
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));
·
·
·
·
1.4.2
Java
AspectJ after
ColorControllingClient
15
AspectJ
aspect ColorControl {
pointcut CCClientCflow(ColorControllingClient client):
cflow(call(* * (..)) && target(client));
1.4.3
com.bigboxco PublicMethodCall
after
aspect PublicErrorLogging {
Log log = new Log();
pointcut publicMethodCall():
call(public * com.bigboxco.*.*(..));
16
AspectJ
aspect ContextFilling {
pointcut parse(JavaParser jp):
call(* JavaParser.parse*(..))
&& target(jp)
&& !call(Stmt parseVarDec(boolean)); // var decs
// are tricky
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
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;
19
AspectJ
Java
Java
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
aspect A {
pointcut fooPC(): execution(void Test.foo());
pointcut gooPC(): execution(void Test.goo());
pointcut printPC(): call(void java.io.PrintStream.println(String));
22
AspectJ
2.3.4
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.
before
before(Point p, int x): target(p) && args(x) && call(void setX(int)) {
if (!p.assertX(x)) return;
}
after
24
AspectJ
2.5.
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; }
25
AspectJ
Point Comparable
declare parents : Point implement Comparable;
Point
Point GeometricObject
declare parents : Point extends GeometricObject;
aspect A {
private interface HasName {}
declare parents: (Point || Line || Square) implements HasName;
2.5.1
AspectJ aspect
int Foo.x;
2.5.2 PointAssertions
class Point {
int x, y;
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
26
AspectJ
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
3.1.
AspectJ
AspectJ
AspectJ
AspectJ
3.2.
AspectJ http://eclipse.org/aspectj
AspectJ examples
.lst arglist ajc
3.3.
AspectJ
28
AspectJ
3.3.1 thisJoinPoint
AspectJ examples/tjp
( ) ( )
thisJoinPoint thisJoinPoint
org.aspectj.lang.JoinPoint
( )
thisJoinPointStaticPart
tjp.Demo tjp/Demo.java
foo bar go main
public class Demo {
static Demo d;
29
AspectJ
void go(){
d = new Demo();
d.foo(1,d);
System.out.println(d.bar(new Integer(3)));
}
30
AspectJ
3.3.2
AspectJ examples/introduction
AspectJ
Point
Point UML
31
AspectJ
CloneablePoint Cloneable
declare parents:
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 );
}
}
declare parents:
main()
public aspect ComparablePoint {
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
p1.offset(1,1);
System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
}
}
main()
public aspect HashablePoint {
p1.setRectangular(10, 10);
Point p2 = new Point();
p2.setRectangular(10, 10);
34
AspectJ
h.put(p1, "P1");
System.out.println("Got: " + h.get(p2));
}
}
3.4.
3.4.1
AspectJ examples/tracing
AspectJ
35
AspectJ
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(* *(..));
tracing.version1.TraceMyClasses
37
AspectJ
38
AspectJ
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
// implementation part
39
AspectJ
// protocol part
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
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;
41
AspectJ
Point
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 firePropertyChange(Point p,
String property,
double oldval,
double newval) {
p.support.firePropertyChange(property,
new Double(oldval),
new Double(newval));
}
}
43
AspectJ
3.5.2 Subject-Observer
Subject/Observer
Observers Subjects
Subject/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 {
Observer Subject
Button java.awt.Button click()
class Button extends java.awt.Button {
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);
}
}
Subject
ColorLabel colorCycle() Observer
class ColorLabel extends Label {
ColorLabel(Display display) {
super();
display.addToFrame(this);
}
import java.util.Vector;
46
AspectJ
}
Button ColorLabel
stateChanges Button ColorLabel button
Demo
subjects observers
3.5.3
Basic Object
Customer Call Connection Connection
Local LongDistance Customer name areaCode call
Connection
47
AspectJ
48
AspectJ
Connection(Customer a, Customer b) {
this.caller = a;
this.receiver = b;
}
49
AspectJ
void complete() {
state = COMPLETE;
System.out.println("connection completed");
}
void drop() {
state = DROPPED;
System.out.println("connection dropped");
}
Timer
TimeLog
class Timer {
50
AspectJ
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;
private
52
AspectJ
TimingSimulation.java report(Customer)
AbstractSimulation Customer Timing
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);
53
AspectJ
Trace.traceEntry("Square.distance", this);
traceEntry traceExit
2 traceEntry
traceExit Trace
Trace
abstract aspect Trace {
54
AspectJ
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(..));
AbstractFacade
pointcut nonAbstract(AbstractFacade af):
call(* *(..))
&& target(af)
&& !if(af.getClass() == AbstractFacade.class);
AbstractFacade
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");
}
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
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.
thisJoinPoint
org.aspectj.lang.JoinPoint
thisJoinPointStaticPart
thisJoinPoint.getStaticPart()
thisEnclosingJoinPointStaticPart
61
AspectJ
4.
4.
4.
PerClause issingleton
62
AspectJ
PerClause
[ issingleton ] aspectOf()
perthis(Pointcut)
Pointcut aspectOf(Object)
pertarget(Pointcut)
Object Pointcut aspectOf(Object)
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
! 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
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);
AspectJ
this(Type or Id)
target(Type or Id)
this this target
target
1
2
68
AspectJ
3 *
4 ..
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.
AspectJ Java
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
3.6.
call(Foo.new())
Foo
call(Foo+.new())
Foo Foo
call(*Handler+.new())
71
AspectJ
4.
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
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;
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
4.3.
74
AspectJ
[1] after
[2]
aspect A {
before(): execution(void main(String[] args)) {}
after(): execution(void main(String[] args)) {}
before(): execution(void main(String[] args)) {}
}
after returning
after throwing
after
4.4.
thisJoinPoint, thisJoinPointStaticPart,
thisEnclosingJoinPointStaticPart
75
AspectJ
5.
AspectJ declare
5.1.
AspectJ
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();
}
}
This
OnType Java static
this
76
AspectJ
5.2.
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.
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
}
79
AspectJ
5.8.
TypePatternList
(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: B, A;
declare precedence: A, B;
A B
A B
80
AspectJ
before(): logged() {
System.err.println("thisJoinPoint: " + thisJoinPoint);
}
}
5.9.
declare
cflow
cflowbelow
this
target
args
if
81
AspectJ
6.
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
Per-control-flow
aspect Id percflow(Pointcut) { ... }
aspect Id percflowbelow(Pointcut) { ... }
A percflow(Pointcut) percflowbelow(Pointcut) A
Pointcut
A
A.aspectOf() A
aspect Watchcall {
pointcut myConstructor(): execution(new(..));
before(): myConstructor() {
System.err.println("Entering Constructor");
}
83
AspectJ
}
Watchcall
Watchcall Watchcal
6.3.
84
AspectJ
C AspectJ
1.
AspectJ AspectJ
JVM
AspectJ
ajc
static
AspectJ
ajc
85
AspectJ
2.
2.1. String+
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
before handler
before(): handler(java.io.IOException) && cflow(void parse()) {
System.out.println("about to handle an exception while parsing");
}
86
AspectJ
2.3.
Java
class C {
double d = Math.sqrt(2);
}
AspectJ
aspect A {
C.new(Object o) {} // implicitly calls super()
this
87
AspectJ
AspectJ Java
AspectJ Java
AspectJ
AspectJ
AspectJ
Java
AspectJ
AspectJ
88
AspectJ
89
AspectJ
90