Download presentation
Presentation is loading. Please wait.
Published byLionel Flynn Modified over 9 years ago
1
Aspect-Oriented Programming with AspectJ Using slides from Jorrit N. Herder ( jnherder@cs.vu.nl )jnherder@cs.vu.nl Mik Kersten ( aspectj.org Palo Alto Research Center )
2
good modularity XML parsing in org.apache.tomcat –red shows relevant lines of code –nicely fits in one box XML parsing
3
good modularity URL pattern matching in org.apache.tomcat –red shows relevant lines of code –nicely fits in two boxes (using inheritance) URL pattern matching
4
good modularity socket creation in Tomcat –colored lines show relevant lines of code –fits nicely into one package (3 classes)
5
pretty good modularity class loading in Tomcat –colored lines show relevant lines of code –mostly in one package (9 classes)
6
not so good modularity logging in Tomcat –scattered across the packages and classes –error handling, security, business rules, …
7
logging, zoomed in //From ContextManager public void service( Request rrequest, Response rresponse ) { // log( "New request " + rrequest ); try { // System.out.print("A"); rrequest.setContextManager( this ); rrequest.setResponse(rresponse); rresponse.setRequest(rrequest); // wront request - parsing error int status=rresponse.getStatus(); if( status < 400 ) status= processRequest( rrequest ); if(status==0) status=authenticate( rrequest, rresponse ); if(status == 0) status=authorize( rrequest, rresponse ); if( status == 0 ) { rrequest.getWrapper().handleRequest(rrequest, rresponse); } else { // something went wrong handleError( rrequest, rresponse, null, status ); } } catch (Throwable t) { handleError( rrequest, rresponse, t, 0 ); } // System.out.print("B"); try { rresponse.finish(); rrequest.recycle(); rresponse.recycle(); } catch( Throwable ex ) { if(debug>0) log( "Error closing request " + ex); } // log( "Done with request " + rrequest ); // System.out.print("C"); return; } // log( "New request " + rrequest ); // System.out.print(“A”); // System.out.print("B"); // log("Done with request " + rrequest); if(debug>0) log("Error closing request " + ex); // System.out.print("C");
8
Without AOP
9
With AOP
13
the cost of tangled code redundant code –same fragment of code in many places difficult to reason about –non-explicit structure –the big picture of the tangling isn’t clear difficult to change –have to find all the code involved –and be sure to change it consistently
14
Cross Cutting Concern What is a crosscutting concern? –Behavior that cuts across the typical divisions of responsibility, such as logging or debugging –A problem which a program tries to solve. –Aspects of a program that do not relate to the core concerns directly, but which proper program execution nevertheless requires.
16
the aop idea crosscutting is inherent in complex systems crosscutting concerns –have a clear purpose –have a natural structure so, let’s capture the structure of crosscutting concerns explicitly... –in a modular way –with linguistic and tool support aspects are –well-modularized crosscutting concerns
23
AspectJ History Java with Aspects Developed at Xerox PARC (Palo Alto RC) Launched in 1998 PARC transferred AspectJ to an openly- developed eclipse.org project in December of 2002. For more info: www.eclipse.org/aspectj
24
Terminology Cross-cutting – Identify areas of code where common functionality exists Advice – The code to be injected Joinpoint – Where one or more aspects can be applied Pointcut – A collection of joinpoints Aspect – General term for where advice and point-cuts are combined
25
Terminology Weaving – Integrating applications and aspects (e.g. AspectJ is an “aspect weaver”) –Compile-time – Can produce integrated source-code, but typically only produces woven byte-code. –Run-time – Aspects are applied “on the fly” (typically when classes are loaded)
27
package com.aspect; public aspect DemoAspect { pointcut setterNotification() : call(* *.set*(..)); before() : setterNotification(){ System.out.println("setting data..."); } Quick Look Point-cut Advice Aspect
28
Language: Join Points Well-defined points in the execution of a program: –Method call, Method execution –Constructor call, Constructor execution –Static initializer execution –Object pre-initialization, Object initialization –Field reference, Field set –Handler execution –Advice execution
29
Joinpoint Types call(method expr) –when a method is called execution(method expr) –when a method is executed handler(exception expr) –when a catch block is executed
30
Defining Joinpoints //call is the most common joinpoint type call([access modifier] returnType package.ClassName.method(args)); //Examples call(* *.*(..)); //Note: “..” is also a wildcard call(public * *.set*(..)); call(void *.set*(..)); call(* *.set*(int)); call(String com.foo.Customer.set*(..)); call(* com.foo.Customer+.set*(..)); //”+” cross-cuts children call(public void com..*.set*(int)); call(* *.set*(int,..)); call(* *.set*(int,.., String));
31
Joinpoint Types get(field expr) –when a field is read set(field expr) –when a field is set staticinitialization(class expr) –when a static block of a class is exectued
32
Joinpoint Types initialization(constructor expr) –when a constructor is executed preinitialization(constructor expr) –when inherited constructors are executed adviceexecution() –when an advice block is executed
33
Language: Pointcuts A set of join point, plus, optionally, some of the values in the execution context of those join points. Can be composed using boolean operators ||, && Matched at runtime
34
Defining Pointcuts public aspect SomeAspect{ pointcut uberPointCut() : call(* *.*(..)); pointcut setterTrace() : call(* *.set*(int,..)); pointcut exceptionTrace() : handler( java.io.Exception+ ); } Defining a pointcut is similar to defining a method Define the pointcut name and the joinpoint type/expression
35
Defining Advice pointcut somePointCut() : call(* *.*(..)); before() : somePointCut(){ System.out.println("Injecting advice..."); } after() : somePointCut(){ System.out.println("Advice injected"); } Advice, is even more similar to defining a method
36
Defining Advice //NOTE: You can streamline your definition of a // joinpoint and advice. before() : call(* *.*(..)) { System.out.println("Injecting advice..."); } //vs. before() : somePointCut(){ System.out.println("Injecting advice..."); }
37
Advice Types before() after() returning after() throwing after() around()
39
Talk outline OOP benefits and shortcomings Different kinds of software properties What is AOP and what are the benefits? How does AOP actually work? An example application in AspectJ Design Patterns and AOP
40
OOP benefits OOP builds on existing paradigms Elegant programming solutions –Inheritance (specialized classes) –Dynamic binding (polymorphic behavior) Maintenance becomes easier –Object model is rather stable Reuse of components is easy OOAD can be used as design method
41
OOP shortcomings OOP allows to decompose a system into units of function or behavior Certain software properties cannot be isolated in single functional unit, instead they crosscut multiple components Such crosscutting concerns result in tangled code that is hard to develop and maintain
42
Software properties (1/2) Components: properties that can be cleanly encapsulated in a unit of function or behavior; like a procedure or object Aspects: cross-cutting concerns that cannot be captured in a functional decomposition; properties affecting the performance or semantics of components
43
Software properties (2/2) Components –GUI elements –Readers and writers –Database Aspects –Debugging –Logging –Synchronization
44
Aspect-Oriented Programming Definition: ''... to support the programmer in cleanly separating components and aspects from each other, by providing mechanisms that allow to abstract and compose them to produce the overal system.''
45
AOP Benefits All benefits of OOP discussed before Separation of components and aspects –Better understanding of software because of high level of abstraction –Easier development and maintenance because tangling of code is prevented –Increased potential for reuse for both components as well as aspects
46
How does AOP work?
47
AOP Infrastructure
48
Cross Cutting Concerns
49
AOP mechanisms Abstraction mechanism: An aspect description language is used to encapsulate crosscutting concerns into modules according to the join point model Composition mechanism: A weaver is used to merge the aspects and components into an application that only contains traditional language constructs
50
Join point model (1/2) Identify “join points” –Points in the execution of components where aspects should be applied –E.g method invocation or object construction –Use “Pointcuts” to collect sets of join points Describe “Advice”, behavior at join points –Wrap join points with extra code before, after execution… in place of, or added to
51
Join point model (2/2) A method call join point:
52
aspect PublicErrorLogging { Log log = new Log(); pointcut publicInterface (): call(public * org.apache.tomcat..*.*(..)); after() throwing (Error e): publicInterface() { log.write(e); } logging, modularized crosscutting concerns –tangled implementation complex, difficult to maintain –modular implementation can be clear, easy to maintain crosscutting concerns per se not complicated! captures public interface of tomcat package
53
Weaving Aspect description languages cannot be processed by tradional compilers Therefore, aspects and components are woven into intermediate source code Weaving is no longer needed if there is an aspect-oriented compiler available This can be compared to preprocessing of C++ code to generate a C representation
54
Illustration of AOP The concepts presented will now be illustrated by an example application in the aspect-oriented language AspectJ Any questions so far?
55
AspectJ Is a general-purpose aspect-oriented extension to Java, which is freely available from http://www.aspectj.org/ Java: defines components as before by encapsulating data and behavior in objects AspectJ: defines aspect modules by describing join points and behavior
56
Pause
57
a simple figure editor operations that move elements factory methods Display * 2 Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Figure makePoint(..) makeLine(..) FigureElement moveBy(int, int)
58
a Line a Point join points returning or throwing dispatch key points in the dynamic call graph a method call returning or throwing a method execution returning or throwing a method execution imagine l.move(2, 2)
59
join point terminology several kinds of join points –method & constructor execution –method & constructor call –field get & set –exception handler execution –static & dynamic initialization a Line dispatch method call join points method execution join points
60
pointcuts: naming join points each execution of the or method or a “void Line.setP2(Point)” execution name and parameters a “void Line.setP1(Point)” execution pointcut move(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point));
61
pointcut move(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); after() returning: move() { } advice: action under joinpoints a Line after advice runs “on the way back out”
62
a simple aspect aspect HistoryUpdating { pointcut move(): exucution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); after() returning: move() { } an aspect defines a special class that can crosscut other classes
63
Problem description Question: ''How to enforce synchronization policies with AOP?'' Suppose multiple objects are concurrently working on some shared data and exclusive access is needed for modification All objects that are working on the data must be synchronized, for example by locking the shared data temporarily
64
interface Observer { /*... the observer design pattern requires that every observer implements this interface...*/ public void update(Subject s); } class ConcreteObserver implements Observer {... public void update(Subject s) { //... get new state from the subject }... }
65
class SharedData { /*... apply singleton design pattern... */ private SharedData instance; private SharedData() { //... initialize shared data object } public static SharedData getInstance() { if (instance == null) instance = new SharedData(); return instance; }... }
66
class Worker extends Thread { /*... multithreading allows concurrent access... */ private SharedData data = SharedData.getInstance(); public void modify() { /* modify data */ //... needs exclusive access! } public void run() { /* start thread */ //... schedule actions to modify() //... according to external circumstances }... }
67
Problem analysis Synchronization is a crosscutting concern that affects all components that are working on the shared data Components: readers, writers, and data Aspect: the locking literally cross-cuts all components that are working on the data
68
Observation Without AOP –Every component that works on the shared data must take care of the locking itself, leading to tangled and complex code With AOP –The locking aspect is separated from the components by means of an aspect module, resulting in usual benefits of modularization
69
aspect ExclusiveAccess { private boolean locked; /* private to aspect */ pointcut access(): /* method call join point */ call( void Worker.modify() ) ; before(Worker worker) : access() && this(worker) { while( ! acquireLock() ) { /* synchronization point */ try { worker.sleep(); } catch(InterruptedException e) { } }
70
//... rest of aspect ExclusiveAccess after() : access() { releaseLock(); /* nothing special */ } private synchronized boolean acquireLock() { if (locked) return false; locked = true; return locked; } private void releaseLock() { locked = false; }
71
Conclusions sofar... Today's programming languages have problems capturing cross-cuttings AOP languages, like AspectJ, provide mechanisms to cleanly abstract from components and aspects Improved modularity allows simpler code that is easier to develop and maintain, and that has greater potential for reuse
72
Design Patterns Design patterns are proven solutions that provide elegant ways for solving frequently occuring problems Effects of AOP on design patterns were studied by analysing Java and AspectJ implementations of Observer, Composite, Visitor, Proxy, Decorator
73
Observations 1. Existing design patterns may be replaced by aspect-oriented patterns that provide a different solution for the same problem 2. Existing object-oriented design patterns may be implemented more modular with aspect-oriented technologies
74
AspectJ constructs Assigning roles to participants –declare parents: Participant implements Role; Attaching pattern functionality –public void Node.accept(Visitor v) { v.visit(this) } Event handling (join points + advice) –abstract pointcut event(Subject s); –after(Subject s): event(s) {... notify observers... }
75
Observer GoF: ''Define one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.'' –Decouple components –Retain a consistent state
76
abstract aspect ObserverProtocol { protected interface Subject {} /* defines role */ protected interface Observer {} /* defines role */ private WeakHashMap perSubjectObservers; public void addObserver(Subject s, Observer o) { //... register observer o of subject s getObservers(s).add(o); } public void removeObserver(Subject s, Observer o) { getObservers(s).remove(o); }...
77
//... rest of aspect ObserverProtocol /* abstract join points after which to do update */ protected abstract poincut subjectChange(Subject s); /* abstract method that does actual observer update */ protected abstract void update(Subject s, Observer o); /* abstract method that does actual observer update */ after(Subject s): subjectChange(s) { Iterator i = getObservers(s).iterator(); while (i.hasNext() ) { update( s, ((Observer) i.next()) ); }
78
aspect ColorObserver extends ObserverProtocol { /* superimpose roles on participating classes */ declare parents: Points implements Subject; declare parents: Screen implements Observer; /* concretize abstract join points of interest */ protected pointcut subjectChange(Subject s): call(void Point.setColor(Color) && target(s); /* concretize behavior if event occurs */ protected void update(Subject s, Observer o) { ((Screen) o).display(''Color changed, screen updated''); }
79
Visitor GoF: ''Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.'' –Node classes independent of operations –Easily define new operations
80
abstract aspect VisitorProtocol { /* define roles for elements in object structure */ public interface VisitorNode {} protected interface VRegularNode extends VisitorNode {} protected interface VLeafNode extends VisitorNode {} /* role interface to be implemented by concrete visitors */ public interface NodeVisitor { //... call-back methods for concrete visitors public void visitRegularNode(VisitorNode node); public void visitLeafNode(VisitorNode node); }...
81
//... rest of aspect VisitorProtocol /* attachment of the double-dispatch protocol */ public void VisitorNode.accept(NodeVisitor v) {} public void VRegularNode.accept(NodeVisitor v) { v.visitRegularNode(this); } public void VLeafNode.accept(NodeVisitor v) { v.visitLeafNode(this); }
82
aspect ConcreteVisitor extends VisitorProtocol { /* superimpose roles on participating classes */ declare parents: Node implements VisitorNode; declare parents: RegularNode implements VRegularNode; declare parents: LeafNode implements VLeafNode; } class MyVisitor implements VP.NodeVisitor {... public void visitRegularNode(VP.VisitorNode node) { // do some operation on a regular node... } public void visitLeafNode(VP.VisitorNode node) { // do some operation on a leaf node... }
83
Decorator GoF: ''Attach additional responsibility to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality.'' –Add extra responsibility or functionality –Control decoration of individual objects based on the context they are in
84
class ConcreteOutput { public void print(String s) { System.out.println(s); } aspect StarDecorator dominates BracketDecorator { /* identify the execution points of interest */ protected pointcut printCall(String s): call( void ConcreteOutput.print(String)) && args(s); /* parameter s is the string to be decorated */ protected void around(String s): printCall(s) { s = '' *** '' + s + '' *** ''; proceed(s); }
86
Bachelor Project Results Patterns with only superimposed roles benefit most from AspectJ, in contrast to patterns with only defining roles Although AspectJ improves modularity of many patterns, sometimes the AspectJ implementation has negative points AspectJ allows separating the mechanism and policy of some design patterns
87
Any Questions? This presentation as well as the bachelor project report with the analysis of pattern implementations in Java and AspectJ can be downloaded from the course website at http://www.cs.vu.nl/~ralf/poosd/
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.