1 Vortrag zum Praktikum „Extreme Programming“ Thema: AspectJ – Eine Aspektorientierte Programmiersprache Von: Sven Bartel Hinweis: Die Folien basieren auf Folien der Vorlesung „Aspect-Oriented Software Development 2004“ (Dr. Günter Kniesel u.M.)
1
Vortrag zum Praktikum „Extreme Programming“
Thema:
AspectJ – Eine Aspektorientierte Programmiersprache
Von: Sven Bartel
Hinweis: Die Folien basieren auf Folien der Vorlesung „Aspect-Oriented Software Development 2004“
(Dr. Günter Kniesel u.M.)
2
AspectJ – Eine Aspektorientierte Programmiersprache
Überblick
1. Motivation
2. Aspektorientierte Programmierung
3. Eine beispielorientierte Einführung in AspectJ
3.1 Beispiel: ein Editor für Figuren3.2 Joinpoints3.3 Pointcuts3.4 Advice3.5 Aspekt
4. Details zu AspectJ
4.1 Wildcards4.2 Der Parameter-Mechanismus4.3 Anwendung: Bedingungen für Methoden4.4 Inter-type Declarations
5. Zusammenfassung
6. Übungsaufgabe
3
AspectJ – Eine Aspektorientierte Programmiersprache
1. Motivation
Grenzen der Objektorientierung:
• Dekomposition führt nicht immer zur „nahtlosen“ Kapselung von Verhaltensweisen
- Beispiele für solche Verhaltensweisen:
o Tracing
o Logging
4
AspectJ – Eine Aspektorientierte Programmiersprache
Schlechte Modularität (1)
Beispiel: Logging in org.apache.tomcat
Quelle: aspectj.org Webseite
• Code auf viele Klassen verteilt
• Logging ist nicht modularisiert – Logging ist ein „crosscutting concern“
- Weitere Beispiele: Sicherheit, Debugging, Synchronisation, Transaktionen,…
1. Motivation
5
AspectJ – Eine Aspektorientierte Programmiersprache 1. Motivation
Schlechte Modularität (2)
Begriffsbildung
• Scattering: Code eines bestimmten Concern ist über verschiedene Teile des Programms verteilt
• Tangling: Code in einem bestimmten Teil adressiert verschiedene Concerns
Folgen
• Redundanz
• schwer nachzuvollziehender Code
• Probleme bei Änderungen
6
AspectJ – Eine Aspektorientierte Programmiersprache
2. Aspektorientierte Programmierung (AOP)
• realisiert cross-cutting concerns als first-class Elemente
• extrahiert cross-cutting concerns von der ursprünglichen Objekt-Struktur
- realisiert diese in einer zusätzlich geschaffenen Dimension
- dabei verwendete Struktur: textuell, genannt „Aspekt“
concerns
ursprünglicheObjekt-Struktur
7
AspectJ – Eine Aspektorientierte Programmiersprache 2. Aspektorientierte Programmierung
Aspekte
Vorteile
• cross-cutting concerns werden modularisiert
• weniger Tangling, bessere Wartbarkeit, kürzerer Code, bessere Wiederverwendbarkeit
concerns
Aspekt
ursprünglicheObjekt-Struktur
8
AspectJ – Eine Aspektorientierte Programmiersprache 2. Aspektorientierte Programmierung
Technische Bestandteile von AOP
1. Modell gibt den Rahmen vor um die Struktur der crosscutting concerns zu definieren (AspectJ: Joinpoints)
2. Mittel zur Identifizierung von Joinpoints (AspectJ: Pointcuts)
3. Mittel zur Beeinflussung des Verhaltens bei Joinpoints (AspectJ: Aspekte)
4. Mittel für das „ Zusammenweben“ zu einem funktionellen System (AspectJ: ajc compiler kompiliert Java und webt Aspekte in Klassen)
9
AspectJ – Eine Aspektorientierte Programmiersprache 2. Aspektorientierte Programmierung
Begriffsbildung: („AOP is Quantification and Obliviousness“ [Filman2004])
• Quantification:
• Welche Mechanismen stehen zur Verfügung um Anwendungen mit Aspekten zu erstellen?
• Welche Prädikate stehen zur Verfügung um Situationen zu beschreiben auf die Aspekte angewendet werden
• Obliviousness:
• Anhand des Basis-Codes ist nicht feststellbar, dass der Aspekt ausgeführt wird
10
AspectJ – Eine Aspektorientierte Programmiersprache
3. Eine beispielorientierte Einführung in AspectJ
Hinweis: Folien orientieren sich am zweiten Teil des Tutorials:
11
AspectJ – Eine Aspektorientierte Programmiersprache
3.1 Beispiel: Ein einfacher Editor für Figuren
FigureElement
Display
Point
setX(int)setY(int)
Line
setP1(Point)setP2(Point)
Figure *
2
makePoint(..)makeLine(..)
moveBy(int, int)
Operationen dieElemente bewegen
factory Methoden
12
AspectJ – Eine Aspektorientierte Programmiersprache
Quelltextauszug
3.1 Beispiel: Ein Editor für Figuren
class Line implements FigureElement{ private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } void moveBy(int dx, int dy) { ... }}
class Point implements FigureElement { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; } void moveBy(int dx, int dy) { ... }}
13
AspectJ – Eine Aspektorientierte Programmiersprache
Aufgabe: Aktualisieren des Displays
• Ansammlung von Figurelementen
- die sich bewegen
- müssen das Display bei Bedarf aktualisieren
- Anzahl der Figurelemente kann komplex sein
- Events treten asynchron auf
3.1 Beispiel: Ein Editor für Figuren
14
AspectJ – Eine Aspektorientierte Programmiersprache
3.2 Joinpoint
• Wohldefinierte Punkte in der Ausführung eines Java-Programms, wie z.B.
- Methodenaufrufe & Konstruktorenaufrufe (call join points)
- Ausführung von Methoden & Konstruktoren (execution call points)
- Feldzugriffe (get & set)
A Line
dispatch
method execution join point
method call join point
15
Aufbau:
public pointcut mypointcut() : call (void Line.setP1(Point))
AspectJ – Eine Aspektorientierte Programmiersprache
3.3 Pointcut (1)
• Prädikat, das eine Menge von Joinpoints definiert
Accessspecifier
Pointcutname
KeywordPointcut
type
Signature
16
AspectJ – Eine Aspektorientierte Programmiersprache
Pointcut (2)
• Beispiel (anonymer Pointcut): call (void Line.setP1(Point))
• Pointcuts können durch Boolesche Ausdrücke logisch verknüpft werden
• Pointcuts können benannt werden
• Pointcuts können über mehrere Klassen selektieren
Beispiel: public pointcut move() :call (void Line.setP1(Point)) ||call (void Line.setP2(Point)) ||call (void Point.setX(int)) ||call (void Point.setY(int));
3.3 Pointcut
17
AspectJ – Eine Aspektorientierte Programmiersprache
Primitive Pointcuts
• call ist ein „Primitiver Pointcut“
3.3 Pointcut
Weitere Primitive Pointcut Bezeichner sind:
- call, execution - this, target, args
- get, set - within, withincode
- handler - cflow, cflowbelow
- initialization, staticinitialization
• Weitere Details: AspectJ Quick Reference
18
AspectJ – Eine Aspektorientierte Programmiersprache
Erläuterung primitiver Pointcuts: call, execution, within
:Test :Poin t
moveBy()se tX()
moveByca ll
moveBy execution
setX call se tXexecution
moveBy()
moveBy call&&
within (Line)moveBy execution
mainexecution
:Line
3.3 Pointcut
19
AspectJ – Eine Aspektorientierte Programmiersprache
3.4 Advice
• Code der einem Pointcut zugeordnet wird
• und damit zusätzliches Verhalten bei den vom Pointcut definierten Joinpoints einführt.
• der Code kann
- vor (before advice)
- nach (after advice)
- während (around advice)
einem Pointcut ausgeführt werden
20
AspectJ – Eine Aspektorientierte Programmiersprache
Beispiel: after advice
a Line
after advice wird aufdem "Rückweg" ausgeführt
3.4 Advice
Varianten:
• after throwing
• after returning
pointcut move():
call (void Line.setP1(Point)) ||call (void Line.setP2(Point));
after() returning: move() {
<nach jedem „move“ auszuführender Code>
}
21
AspectJ – Eine Aspektorientierte Programmiersprache
3.5 Aspekt
• Repräsentation eines „crosscutting concerns“ im Code
• Aspekte
- ähneln einer Klasse
- können Methoden, Felder, Pointcuts und Advices beinhalten
- können abstract sein
- können von Klassen abgeleitet werden und Interfaces implementieren
22
AspectJ – Eine Aspektorientierte Programmiersprache
Beispiel: Ein einfacher Aspekt
ohne AspectJ:
3.5 Aspekt
Box impliziert vollständig lauffähigen Code
class Line { private Point p1, p2;
Point getP1() { return p1; } Point getP2() { return p2; }
void setP1(Point p1) { this.p1 = p1; Display.update(); } void setP2(Point p2) { this.p2 = p2; Display.update(); }}
aspect DisplayUpdating {
pointcut move(): call(void Line.setP1(Point)) || call(void Line.setP2(Point));
after() returning: move() { Display.update(); }}
mit AspectJ:
23
AspectJ – Eine Aspektorientierte Programmiersprache
4. Details zu AspectJ
4.1 Wildcards
* beliebiger Teil einer Klasse, Interface oder eines Package
.. alle direkten und indirekten subpackages
+ alle Subtypen (Subklassen oder Subinterfaces)
Beispiel: javax..*Model+
24
Übung: Signaturen (1)
Wiederholung:
AspectJ – Eine Aspektorientierte Programmiersprache 4.2 Wildcards
public pointcut mypointcut() : call (void Line.setP1(Point))
Accessspecifier
Pointcutname
KeywordPointcut
type
Signature
25
Übung: Signaturen (2)
AspectJ – Eine Aspektorientierte Programmiersprache 4.2 Wildcards
• public void Line.*()
• public * Line.*()
• public * Line.*(..)
• !public * Line.*(..)
• * Line+.*(..)
• public void Line.set*(*)
26
AspectJ – Eine Aspektorientierte Programmiersprache
4.2 Parameter-Mechanismus
Ergänzung:
target(Line)
• selektiert alle Joinpoints, falls
• das Objekt, auf dem die Methode aufgerufen wird, instanceof Line ist
• (entsprechend gilt dies für Subklassen von Line)
27
AspectJ – Eine Aspektorientierte Programmiersprache
4.2 Parameter-Mechanismus
before (FigureElement fe) : move(fe) {
System.out.println( fe + “ is about to move”);
}
pointcut move(FigureElement figElt): target(figElt) && (call(void FigureElement.moveBy(int, int))
28
AspectJ – Eine Aspektorientierte Programmiersprache
Aspekt: Aktualisieren des Displays
aspect DisplayUpdating {
pointcut move(FigureElement figElt): target(figElt) && (call(void FigureElement.moveBy(int, int) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Point.setX(int)) || call(void Point.setY(int)));
after(FigureElement fe) returning: move(fe) { Display.update(fe); }}
4.2 Der Parameter-Mechanismus
Demonstration des AJDT
29
AspectJ – Eine Aspektorientierte Programmiersprache
4.3 Anwendung: Bedingungen für Methoden
• Vorbedingungen: Prüfe, ob die Parameter gültig sind
• Nachbedingungen: Prüfe, ob die berechneten Werte gültig sind
• Während der Ausführung: Korrekte Werte erzwingen
30
AspectJ – Eine Aspektorientierte Programmiersprache
Einschub
1) proceed
<result type> proceed(arg1, arg2, …)
• nur im around advice
2) args
Beispiel: args(String,..,int)
• selektiert Joinpoints
• in allen Methoden, die als ersten Parameter String und als letzten int erwarten
4.3 Anwendung: Bedingungen für Methoden
31
AspectJ – Eine Aspektorientierte Programmiersprache
Vorbedingungen
4.3 Anwendung: Bedingungen für Methoden
aspect PointBoundsPreCondition { before(int newX): call(void Point.setX(int)) && args(newX) { assert(newX >= MIN_X); assert(newX <= MAX_X); } before(int newY): call(void Point.setY(int)) && args(newY) { assert(newY >= MIN_Y); assert(newY <= MAX_Y); }
private void assert(boolean v) { if ( !v ) throw new RuntimeException(); }}
nach dem ‘:’ folgt immer ein pointcut – primitiv oder benannt (selbst-definiert)
32
AspectJ – Eine Aspektorientierte Programmiersprache
Nachbedingung
4.3 Anwendung: Bedingungen für Methoden
aspect PointBoundsPostCondition {
after(Point p, int newX) returning: call(void Point.setX(int)) && target(p) && args(newX) { assert(p.getX() == newX); }
after(Point p, int newY) returning: call(void Point.setY(int)) && target(p) && args(newY) { assert(p.getY() == newY); }
private void assert(boolean v) { if ( !v ) throw new RuntimeException(); }}
33
AspectJ – Eine Aspektorientierte Programmiersprache
Während der Ausführung: korrekte Werte forcieren
4.3 Anwendung: Bedingungen für Methoden
aspect PointBoundsEnforcement {
void around(Point p, int newX): call(void Point.setX(int)) && target(p) && args(newX) { proceed(p, clip(newX, MIN_X, MAX_X)); }
void around(Point p, int newY): call(void Point.setY(int)) && target(p) && args(newY) { proceed(p, clip(newY, MIN_Y, MAX_Y)); }
private int clip(int val, int min, int max) { return Math.max(min, Math.min(max, val)); }}
Demo
34
AspectJ – Eine Aspektorientierte Programmiersprache
4.4 Inter-type Declarations
Beispiele:
• declare parents : C extends D;
• declare parents : C implements I,J;
• declare warning : set(* Point.*)&&!within(Point) : „bad set“ ;
Demo
• pointcut illegalNewFigElt(): (call(Point.new(..)) || call(Line.new(..))) && !withincode(* Figure.make*(..));
declare error: illegalNewFigElt():"Use factory method instead.";
35
AspectJ – Eine Aspektorientierte Programmiersprache
5. Zusammenfassung
• „AOP is Quantification and Obliviousness“
AspectJ:
• Joinpoints: Wohldefinierte Punkte in der Ausführung eines Java-Programms
• Pointcuts: Prädikat, das eine Menge von Joinpoints definiert (primitiv + selbst-definiert)
• Advice: Code der einem Pointcut zugeordnet wird und damit zusätzliches Verhalten bei den vom Pointcut definierten Joinpoints einführt
• Aspekt: Repräsentation eines „crosscutting concerns“ im Code
• Details zu AspectJ:
• Wildcards• Parameter-Mechanismus• Inter-type Declarations
36
AspectJ – Eine Aspektorientierte Programmiersprache
6. Übungsaufgabe: Caching von Fibonacci-Zahlen
public class Fibonacci {
// naive implementation of fibonacci // with a lot of redundant calculations of the same values. public static int fib(int n) { if ( n < 2) { System.out.println(n + "."); return 1; } else { System.out.print(n + ","); return fib(n-1) + fib(n-2); } }
public static void main(String[] args) { int value=10; int f = fib(value); System.out.println("fib("+value+") = " + f); }
}
37
AspectJ – Eine Aspektorientierte Programmiersprache
Lösung..
6. Übungsaufgabe
38
AspectJ – Eine Aspektorientierte Programmiersprache
Mögliche Lösung der Übungsaufgabe:
import java.util.HashMap;
public aspect OptimizeFibonacciAspect {
private HashMap cache = new HashMap();
private pointcut fibs(int n): call(int Fibonacci.fib(int)) && args(n);
int around(int n): fibs(n) { Integer result = (Integer)cache.get(new Integer(n)); if (result == null) { // not found, calculate! int f = proceed(n); cache.put(new Integer(n), new Integer(f)); return f; } else return result.intValue(); // found, done! }
}
6. Übungsaufgabe
39
AspectJ – Eine Aspektorientierte Programmiersprache
7. Anhang
7.1 Control-Flow
Wiederholter Aufruf von call resultiert in neuen J oinpoints
a Line
a Figure
Alle dargestellten Joinpoints sindInnerhalb des Control Flows
dieses Joinpoints
40
AspectJ – Eine Aspektorientierte Programmiersprache
7.1 Erläuterung primitiver Pointcuts: call, execution, within
:Test :Point
moveBy()setX()
moveBycall
moveBy execution
setX call setXexecution
moveBy()
moveBy call&&
within(Line)moveBy execution
mainexecution
:Line
41
AspectJ – Eine Aspektorientierte Programmiersprache
7.2 Erläuterung primitiver Pointcuts: cflow, cflowbelow
:Test :Point:Line
moveBy()moveBy()
setX()
cflow(call(* Line.moveBy()))selektiert alle joinpoints in diesem Bereich
cflow(call(* Line.moveBy()))selektiert alle joinpoints in diesem Bereich
cflowbelow(call(* Line.moveBy()))selektiert alle joinpoints in diesem Bereich
cflowbelow(call(* Line.moveBy()))selektiert alle joinpoints in diesem Bereich
42
AspectJ – Eine Aspektorientierte Programmiersprache
7.3 Webzeit in AspectJ