Aspect Oriented Development (original) (raw)
1. Aspect Oriented Development Viraj Brian Wijesuriya vbw@ucsc.cmb.ac.lk 1 SCS 4120 - Software Engineering IV BACHELOR OF SCIENCE HONOURS IN COMPUTER SCIENCE BACHELOR OF SCIENCE HONOURS IN SOFTWARE ENGINEERING All in One Place Lecture Notes Distribution Among Friends Only All copyrights belong to their respective owners
2. • Procedural programming – Executing a set of commands in a given sequence – Fortran, C, Cobol • Functional programming – Evaluating a function defined in terms of other functions – Lisp, ML, SCALA • Logic programming – Proving a theorem by finding values for the free variables – Prolog • Object-oriented programming (OOP) – Organizing a set of objects, each with its own set of responsibilities – Smalltalk, Java, C++ (to some extent) • Aspect-oriented programming (AOP) – Executing code whenever a program shows certain behaviors – AspectJ (a Java extension) – Does not replace O-O programming, but rather complements it SEIV – AOD – Introduction 2 Types of Programming Paradigms
3. • Some programming tasks cannot be neatly encapsulated in objects, but must be scattered throughout the code • Examples: – Logging (tracking program behavior to a file) – Profiling (determining where a program spends its time) – Tracing (determining what methods are called when) – Session tracking, session expiration – Special security management • The result is crosscuting code--the necessary code “cuts across” many different classes and methods SEIV – AOD – Introduction 3 The Problem!
4. SEIV – AOD – Introduction 4 The Problem!
5. • Concern – A specific requirement or consideration that must be addressed in order to satisfy the overall system goal – E.g. Banking system: Customer and Account management, Interbanking transactions, ATM transactions, Persistence of all entities, Transaction integrity, Authorization of access to various services, Logging, Security, Error checking, Policy enforcement SEIV – AOD – Introduction 5 What is a Concern?
6. • Core concerns – Central functionality of a Business logic (single module) – Customer and Account management, Interbanking transactions, ATM transactions • Crosscut concerns – System-level, peripheral requirements (multiple modules) – Persistence of all entities, Transaction integrity, Authorization of access to various services, logging, Security, Error checking, Policy enforcement • Reliability (logging, tracing) • Security (authentication, authorization) • Correctness (invariant maintenance) • Performance (buffering, pooling, caching) • Functionality (billing, taxes) SEIV – AOD – Introduction 6 Types of concerns
7. • Spectators – no control or heap effects: – Reliability (logging, tracing) • Curbing – only control effects: – Security (authentication, authorization) • Assistants – control and heap effects: – Correctness (invariant maintenance) – Performance (buffering, pooling, caching) – Functionality (billing, taxes) SEIV – AOD – Introduction 7 Kinds of concerns
8. • Each subject type adds: –Code for managing set of listeners/observers –Method, “notify” that calls each listener’s “actionPerformed” method –Calls to notify for each event • Problems: –Scattering and Tangling of: • Calls to notify • Calls to register listeners –Cost of notify calls, even if no listeners SEIV – AOD – Introduction 8 Use of Observer Pattern
9. • Audit Trail – when messages sent/received record message summary and time • Pooling: – when call DriverManager.getConnection() get connection from pool of connections. • Buffering – when call FileOutputSteam.write(), buffer the output SEIV – AOD – Introduction 9 Examples of crosscutting concerns
10. SEIV – AOD – Introduction 10 A Typical Application Accounting ATM Database System Persistence Logging Business Logic Concern Persistence Logging Implementation modules Accounting ATM Database System Persistence Logging
11. • Large, complex distributed systems with many competing concerns – Cross cutting concerns affect modularization – In computer programming, boilerplate code or boilerplate refers to sections of code that have to be included in many places with little or no alteration. • Scattering – The specification of one property is not encapsulated in a single requirement unit. E.g. A use case – repeating code in many modules • Tangling – Each requirement unit contains description of several properties or different functionalities. – mixing concern code with business logic • Problems with Scattering and Tangling – Poor traceability – Lower productivity – Less code reuse – Harder refactoring SEIV – AOD – Introduction 11 Need for Separation of Concerns
12. • Scattering: – Hard to find/change/audit/verify policies • Tangling: – Hard to read code – if (tpm.validUser()) { logger.put(…); o.send(…); … } SEIV – AOD – Introduction 12 Why Avoid Scattering and Tangling …
13. • Quantification (lack of scattering) – Code for each concern in one place – Eases maintenance – Ease of auditing/verification • Obliviousness (lack of tangling) – Code for each concern modularized, independent – Easier to read code for “business logic” SEIV – AOD – Introduction 13 AOP Advantage …
14. • Meta-programming – Difficult for average programmer – Hard to read other people’s programs • Implicit Invocation Languages – Automate Observer pattern – Still have some scattering/tangling for event announcement, registration – Can’t replace/stop events ==> no support for assistance SEIV – AOD – Introduction 14 Other Linguistic Solutions
15. • Modularizing large programs (telecom) • Adding new behavior (e.g., authentication) • Software product lines • Performance improvements (special cases run faster) SEIV – AOD – Introduction 15 Uses of AOP
16. • logging in org.apache.tomcat – each bar shows one module – red shows lines of code that handle logging – not in just one place, not even in a small number of places SEIV – AOD – Introduction 16 Example of Scattering
17. • class Fraction { int numerator; int denominator; ... public Fraction multiply(Fraction that) { traceEnter("multiply", new Object[] {that}); Fraction result = new Fraction( this.numerator * that.numerator, this.denominator * that.denominator); result = result.reduceToLowestTerms(); traceExit("multiply", result); return result; } ... } SEIV – AOD – Introduction 17 Example - Boilerplating • Now imagine similar code in every method you might want to trace
18. • 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 – and be sure not to break it by accident • Inefficient when crosscutting code is not needed SEIV – AOD – Introduction 18 Problems arising with Cross cutting Concerns
19. SEIV – AOD – Introduction 19 Traditional Implementation of CC Accounting Module ATM Module Database Module Logging Module API invocations
20. SEIV – AOD – Introduction 20 AOP Implementation of CC Accounting Module ATM Module Database Module Logging ModuleLogging Aspect API Invocation Automatically Weaving Invocations Aspect: A modular unit of crosscutting concern implementation
21. • AOP is a programming paradigm which aims to increase modularity by allowing the separation of cross-cutting concerns. • The idea behind AOP is “Separation of concern”. AOP is complementary to OOP. • AOP builds upon Existing Methodologies (OOP, Procedural programming), augmenting them with concepts and constructs in order to modularize crosscutting concerns. • Benefits – Centralize concerns implementation – Intercept method calls – Inject new behaviour – More reusable code – Cleaner code • So You – Write less code – Read less code – More concise and easy to understand – More maintainable SEIV – AOD – Introduction 21 What is Aspect Oriented Programming (1)
22. • a learned intuitive way of thinking • design concepts – aspects, crosscutting structure • supporting mechanisms – join points, pointcuts, advice… • allows us to – make code look like the design – improve design and code modularity SEIV – AOD – Introduction 22 What is Aspect Oriented Programming (2)
23. – Fewer code = Fewer defects – Less boilerplate code – More interesting work – Increased attention – More PRODUCTIVITY! • You can do AOP via: – Dynamic Proxies – Functional Programming – Code Generation – Dynamic Languages – Static Weaving (e.g. AspectJ) SEIV – AOD – Introduction 23 Benefits of Aspect Oriented Programming
24. SEIV – AOD – Introduction 24 Example Application a simple drawing application (JHotDraw)
25. SEIV – AOD – Introduction 25 Example Application - Class Diagram • Points, Lines… • Drawing surfaces • GUI Widgets • … Display 2Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) *
26. SEIV – AOD – Introduction 26 Example Application – Dev in 1960s most programmers would have used this has poor design and code modularity! collection of procedures to operate on and manage table entries +
27. SEIV – AOD – Introduction 27 Example Application – Concerns don’t fit class Point extends Shape { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; display.update(this); } void setY(int y) { this.y = y; display.update(this); } } fair design modularity but poor code modularity 1 Display 2Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) * i.e. a simple Observer pattern
28. SEIV – AOD – Introduction 28 Example Application – AOP Way aspect ObserverPattern { private Display Shape.display; pointcut change(): call(void figures.Point.setX(int)) || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Shape.moveBy(int, int)); after(Shape s) returning: change() && target(s) { s.display.update(); } } ObserverPattern 1 Display 2Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape moveBy(int, int) * good design modularity good code modularity
29. SEIV – AOD – Introduction 29 Example Application – How Normal Devs See operations that change shapes factory methods Display 2Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) *
30. SEIV – AOD – Introduction 30 Example Application – How AOP Devs See Display 2Point getX() getY() setX(int) setY(int) moveBy(int, int) Line getP1() getP2() setP1(Point) setP2(Point) moveBy(int, int) Shape makePoint(..) makeLine(..) moveBy(int, int) * FactoryEnforcement ObserverPattern BoundsChecking
31. SEIV – AOD – Introduction 31 Aspect Oriented Dev Stages Business Logic Security Logging Persistence Identify concerns Integrating all concerns
32. • Aspectual Decomposition – Identify primary and cross-cutting concerns • Concern Implementation – Implement concerns separately – Primary concern as Core Component using OO – Cross-cutting concerns as aspects • Aspectual Recomposition – Aspect weaver to weave the separately implemented code into a final system SEIV – AOD – Introduction 32 Aspect Dev Stages Explained!
33. SEIV – AOD – Introduction 33 Aspect Dev Stages Explained! Aspect Decomposition Aspects Core program Aspect Recomposition Requirements Final System
34. • In AOP crosscutting concerns are implemented in aspects instead of fusing them into core modules. • Aspects are an additional unit of modularity. • Aspects can be reused. • By reducing code tangling it makes it easier to understand what the core functionality of a module is. • An “aspect weaver” takes the aspects and the core modules and composes the final system. SEIV – AOD – Introduction 34 What are aspects?
35. • Weaving rules specify how to integrate the final system. • Can be implemented in various ways: – Source to source translation. – Bytecode enhancement, first compile source with original compiler, then weave aspects into class files. – Just-in-time weaving done by a classloader. – By the language compiler. • The JAsCo language supports runtime weaving and unweaving. SEIV – AOD – Introduction 35 Aspect Weaving
36. • AOP aims at providing better means of addressing the well- known problem of separation of concerns • Three basic approaches to addressing the process of separation of concerns: – language-based – framework-based – architecture-oriented • Language Based – It is based on the definition of a set of language constructs – Relevant concerns are identified at the problem domain and translated to aspectual construct – The final application is obtained by weaving the primary structure with the crosscutting aspects SEIV – AOD – Introduction 36 Role of Aspects in Software Design
37. • Framework based – Provides more flexible constructs – Concerns are materialized as aspectual classes at the framework level – Developers can customize these aspects using the mechanism supported by the framework – These types of framework are known as AO frameworks (explicitly engineers concerns) • Architecture-oriented approach – Early identification of concerns using architectural organizational models – Architectural view-point involves a higher level of abstraction than the previous approaches – It typically comprises two stages • First, developers should determine the problem architecture - Concerns are initially mapped to architectural construct • Then, the approach enables several kinds of aspect materialization through different frameworks SEIV – AOD – Introduction 37 Role of Aspects in Software Design
38. • AspectJ is a small, well-integrated extension to Java – Based on the 1997 PhD thesis by Christina Lopes, A Language Framework for Distributed Programming • Uses 2 ‘join point’ models – Pointcuts and advice – Inter-type declarations • AspectJ modularizes crosscutting concerns – That is, code for one aspect of the program (such as tracing) is collected together in one place • The AspectJ compiler is free and open source • AspectJ works with JBuilder, Eclipse, probably others • Best online writeup: http://www.eclipse.org/aspectj/ SEIV – AOD – AspectJ – Introduction 38 AspectJ
39. SEIV – AOD – AspectJ – 1st Join Point Model 39 Example Program 1 Public class Logging{//class public void check( ) { System.out.println("Inside Logging Class Method"); }} public class ATM { //class public void foo(int number, String name) { System.out.println("Inside foo Method"); } public static void main(String[] args) { MyClass myObject = new MyClass( ); myObject.foo(1, “SIT"); } } public aspect Log { //Aspect pointcut callPointcut( ) : call(void ATM.foo(int, String)); //Pointcut before( ) : callPointcut( ) { //Advice System.out.println( “I am from Log aspect"); Logging logg= new Logging(); logg.check(); } } Name of Pointcut before after around
40. SEIV – AOD – AspectJ – 1st Join Point Model Example Program 2 • A pointcut named move that chooses various method calls: – 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)); • Advice (code) that runs before the move pointcut: – before(): move() { System.out.println("About to move"); } • Advice that runs after the move pointcut: – after(): move() { System.out.println("Just successfully moved"); } 40
41. SEIV – AOD – AspectJ – 1st Join Point Model 41 AspectJ Joint Point Model • Any identifiable execution point: – method body – method call – constructor body – constructor call – field access – catch block – class (static) initialization – object initialization – object pre-initialization – advice execution • All join points have a context. Certain pointcuts can capture the context and pass it to the advice.
42. SEIV – AOD – AspectJ – 1st Join Point Model 42 Capture Context Example public class Employee { int salary; public void setSalary(int salary) { this.salary = salary; } public static void main(String[] args) { Employee emp = new Employee(); emp.setSalary(50000); System.out.println("Salary: " + emp.salary); } } public aspect MoneyAspect { pointcut employeePC(int salary) : call(* Employee.setSalary(..)) && args(salary) ; void around(int salary) : employeePC(salary) { salary *= 2; proceed(salary); } } Output: Salary: 100000
43. • A join point is a well-defined point in the program flow • A pointcut is a group of join points • Advice is code that is executed at a pointcut • Introduction modifies the members of a class and the relationships between classes • An aspect is a module for handling crosscutting concerns – Aspects are defined in terms of pointcuts, advice, and introduction – Aspects are reusable and inheritable • Weaving – Combines advices with point cuts • Compile time declaration – Add compile time errors and warnings upon detecting certain usage patterns. • Every valid Java program is a valid AspectJ program SEIV – AOD – AspectJ – 1st Join Point Model 43 Some Terms
44. SEIV – AOD – AspectJ – 1st Join Point Model 44 Method Execution Join Points :Point • method execution join point • the entry/exit to the execution • not the source code setX(int)
45. 45 Method Execution Join Points :Line end1:Point moveBy(int, int) moveBy(int, int) setX(int) setY(int) moveBy(int, int) setX(int) setY(int) end2:Point SEIV – AOD – AspectJ – 1st Join Point Model
46. 46 Method Call Join Points :Line end1:Point moveBy(int, int) moveBy(int, int) setX(int) setY(int) moveBy(int, int) setX(int) setY(int) end2:Point SEIV – AOD – AspectJ – 1st Join Point Model
47. Dynamic Join Points • Dynamic Join Points are well-defined points in flow of execution 47 all dynamic join points on this slide are within the control flow of this dynamic join point :Line end1:Point moveBy(int, int) moveBy(int, int) setX(int) setY(int) moveBy(int, int) setX(int) setY(int) end2:Point SEIV – AOD – AspectJ – 1st Join Point Model
48. • A join point is a well-defined point in the program flow – We want to execute some code (“advice”) each time a join point is reached – We do not want to clutter up the code with explicit indicators saying “This is a join point” – AspectJ provides a syntax for indicating these join points “from outside” the actual code • A join point is a point in the program flow “where something happens” – Examples: • When a method is called • When an exception is thrown • When a variable is accessed 48 Join Points SEIV – AOD – AspectJ – 1st Join Point Model
49. • Pointcut definitions consist of a left-hand side and a right-hand side, separated by a colon – The left-hand side consists of the pointcut name and the pointcut parameters (i.e. the data available when the events happen) – The right-hand side consists of the pointcut itself • Example pointcut: pointcut setter(): call(void setX(int)); – The name of this pointcut is setter – The pointcut has no parameters – The pointcut itself is call(void setX(int)) – The pointcut refers to any time the void setX(int) method is called 49 Pointcuts SEIV – AOD – AspectJ – 1st Join Point Model
50. • Can be named or anonymous. • Named pointcuts: [access-specifier] pointcut pointcut-name( [args] ) : pointcut-definition ; • The pointcut-definition part consists of anonymous pointcuts • Anonymous pointcut used in advice definition: before() : call(* Account.*(..)) { ... advice body } 50 Pointcuts (cont.) SEIV – AOD – AspectJ – 1st Join Point Model
51. 51 Pointcuts (cont.) • Pointcuts can use combinations of other pointcuts. pointcut employeeCalls() : call(* Employee.*(..)); pointcut internalOperations() : employeeCalls() && within(banking..*); • Wildcards can be used to capture join points that share common characteristics. * denotes any number of characters except a period .. denotes any number of characters + denotes any subclass of a given type • Can use operators &&, || and ! within a pointcut definition. SEIV – AOD – AspectJ – 1st Join Point Model
52. Pointcuts (cont.) • 2 types of pointcuts – Kinded and non-kinded 52 Kinded pointcuts capture exposed join points. Method execution execution(MethodSignature) Method call call(MethodSignature) Constructor execution execution(ConstructorSignature) Constructor call call(ConstructorSignature) Class initialization staticinitialization(TypeSignature) Field read access get(FieldSignature) Field write access set(FieldSignature) Exception handler execution handler(TypeSignature) Object initialization initialization(ConstructorSignature) Object pre-initialization preinitialization(ConstructorSignature) Advice execution adviceexecution() Join point category Pointcut syntax SEIV – AOD – AspectJ – 1st Join Point Model
53. Pointcuts (cont.) • Unlike kinded pointcuts (method execution, field access, object initialization …), non-kinded pointcuts select join point on some criteria other than the join point signature (no kind). • For example it is possible to select join points inside the source code(lexical structure) of a Java class or method. 53 public aspect WithinAspects { // Matches all poincuts in source code of com.techweb.test.DummyClass pointcut withinPoincut() : within(com.techweb.test.DummyClass); after() : withinPoincut() { System.out.println("Join Point : "+thisJoinPoint.toLongString()); } } SEIV – AOD – AspectJ – 1st Join Point Model
54. Primitive Pointcuts - call, execution - get, set - handler - initialization, staticinitialization - within, withincode - this, target, args - cflow, cflowbelow 54 SEIV – AOD – AspectJ – 1st Join Point Model
55. User-defined Pointcuts 55 user-defined (aka named) pointcuts – can be used in the same way as primitive pointcuts pointcut change(): execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)); name parameters SEIV – AOD – AspectJ – 1st Join Point Model
56. Control-flow based Pointcuts • Capture all the join points within the control flow of a join point. • cflow(call(* Account.debit(..))) – All the join points within the control flow of any debit method in the Account class, including the call to debit(). • cflowbelow(call(* Account.debit(..))) – Same as above but not including the call to debit(). It doesn’t capture the join point specified as argument, but captures all other join points that comes below that. • cflowbelow can be used to select non-recursive calls. 56 SEIV – AOD – AspectJ – 1st Join Point Model
57. Pointcuts that capture context 57 • this() – the current object • target() – target object of a method call • args() – arguments passed to a method or constructor – exception caught by a handler join point – new value to be set in a field write access this.obj.doSomething(val) this() target() args() SEIV – AOD – AspectJ – 1st Join Point Model
58. Pointcut Designators • When a particular method body executes: – execution(void Point.setX(int)) • When a method is called: – call(void Point.setX(int)) • When an exception handler executes: – handler(ArrayOutOfBoundsException) • When the object currently executing (i.e. this) is of type SomeType: – this(SomeType) 58 SEIV – AOD – AspectJ – 1st Join Point Model
59. Pointcut Designators (contd.) • When the target object is of type SomeType – target(SomeType) • When the executing code belongs to class MyClass – within(MyClass) • When the join point is in the control flow of a call to a Test's no-argument main method – cflow(call(void Test.main())) 59 SEIV – AOD – AspectJ – 1st Join Point Model
60. Pointcut Designators Wildcards • It is possible to use wildcards to declare pointcuts: – execution(* *(..)) • Chooses the execution of any method regardless of return or parameter types – call(* set(..)) • Chooses the call to any method named set regardless of return or parameter type • In case of overloading there may be more than one such set method; this pointcut picks out calls to all of them 60 SEIV – AOD – AspectJ – 1st Join Point Model
61. Pointcut Designators based on type • You can select elements based on types. For example, – execution(int *()) • Chooses the execution of any method with no parameters that returns an int – call(* setY(long)) • Chooses the call to any setY method that takes a long as an argument, regardless of return type or declaring type – call(* Point.setY(int)) • Chooses the call to any of Point’s setY methods that take an int as an argument, regardless of return type – call(*.new(int, int)) • Chooses the call to any classes’ constructor, so long as it takes exactly two ints as arguments 61 SEIV – AOD – AspectJ – 1st Join Point Model
62. Pointcut Designator Composition • Pointcuts compose through the operations or (“||”), and (“&&”) and not (“!”) • Examples: – target(Point) && call(int *()) • Chooses any call to an int method with no arguments on an instance of Point, regardless of its name – call(* *(..)) && (within(Line) || within(Point)) • Chooses any call to any method where the call is made from the code in Point’s or Line’s type declaration – within(*) && execution(*.new(int)) • Chooses the execution of any constructor taking exactly one int argument, regardless of where the call is made from – !this(Point) && call(int *(..)) • Chooses any method call to an int method when the executing object is any type except Point 62 SEIV – AOD – AspectJ – 1st Join Point Model
63. Pointcut Designators on modifiers • call(public * *(..)) – Chooses any call to a public method • execution(!static * *(..)) – Chooses any execution of a non-static method • execution(public !static * *(..)) – Chooses any execution of a public, non-static method • Pointcut designators can be based on interfaces as well as on classes 63 SEIV – AOD – AspectJ – 1st Join Point Model
64. Example Program 2 repeated • A pointcut named move that chooses various method calls: – 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)); • Advice (code) that runs before the move pointcut: – before(): move() { System.out.println("About to move"); } • Advice that runs after the move pointcut: – after(): move() { System.out.println("Just successfully moved"); } 64 SEIV – AOD – AspectJ – 1st Join Point Model
65. Advice • Construct that expresses the action to be taken at the join points that are captured by a pointcut. • AspectJ has several kinds of advice; here are some of them: – Before advice runs as a join point is reached, before the program proceeds with the join point – After advice on a particular join point runs after the program proceeds with that join point • after returning advice is executed after a method returns normally • after throwing advice is executed after a method returns by throwing an exception • after advice is executed after a method returns, regardless of whether it returns normally or by throwing an exception – Around advice on a join point runs as the join point is reached, and has explicit control over whether the program proceeds with the join point • can continue original execution, bypass execution or cause execution with an altered context • can cause execution of the join point multiple times 65 SEIV – AOD – AspectJ – 1st Join Point Model
66. Advice Example 1 public aspect AccountAspect { void around(Account account, float amount) : call(* Account.withdraw(float)) && target(account) && args(amount) { System.out.println("Before withdrawl of amount: " + amount); if(amount > account.getBalance()) System.out.println("Cannot make withdrawl"); else { proceed(account, amount); System.out.println("Withdrawl successful, balance: " + account.getBalance()); } } } 66 SEIV – AOD – AspectJ – 1st Join Point Model
67. Advice Example 2 • You can access the context of the join point: • 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 + ")."); } 67 SEIV – AOD – AspectJ – 1st Join Point Model
68. Aspects • Aspects can: – Include data members and methods. – Be declared abstract (won’t be weaved). – Have access specifiers. – Extend classes or aspects. – Implement interfaces. • Aspects are not the same as classes: – Cannot be directly instantiated. – Cannot inherit from concrete aspects. – Can be marked as privileged • Say you perform some logging from your Aspect, but the member you want to access has no (public) accessor method. You could create a public getter method and use that. Better would be to make the Aspect privileged so it can access the member even though it is declared private. 68 SEIV – AOD – AspectJ – 1st Join Point Model
69. Aspects Example 1 – Multi-class aspect 69 aspect ObserverPattern { pointcut change(): execution(void Shape.moveBy(int, int)) || execution(void Line.setP1(Point)) || execution(void Line.setP2(Point)) || execution(void Point.setX(int)) || execution(void Point.setY(int)); after() returning: change() { Display.update(); } } SEIV – AOD – AspectJ – 1st Join Point Model
70. Aspects Example 2 – Abstract aspect 70 public abstract aspect AbstractLogging { public pointcut logPoints() : call(* *.*(..)); public abstract Logger getLogger(); before() : logPoints() { getLogger().log(Level.INFO, thisJoinPoint.toString()); } } public aspect FactorialLoggingAspect extends AbstractLogging { // pointcut override public pointcut logPoints() : call(* *.factorial(..)); public Logger getLogger() { return Logger.global; } } SEIV – AOD – AspectJ – 1st Join Point Model
71. 2nd Join Point Model • inter-type declarations – aka introductions – aka open classes • for defining methods, fields • join points – member declarations • means of identifying join points – type patterns and signatures • means of effecting join points – declare member 71 SEIV – AOD – AspectJ – 2nd Join Point Model
72. 2nd Join Point Model – Static Crosscutting • Dynamic crosscutting modifies the execution behavior of the program. • Static crosscutting modifies the structure of the program. – Member introduction. – Type-hierarchy modification. – Compile-time warning declaration. – Exception softening. • Member introduction adds data members and methods to classes. 72 SEIV – AOD – AspectJ – 2nd Join Point Model
73. Inter-type declarations • Inter-type declarations provide a way to express crosscutting concerns affecting the structure of modules. • Also known as open classes and extension methods, this enables programmers to declare in one place members or parents of another class, typically in order to combine all the code related to a concern in one aspect. 73 SEIV – AOD – AspectJ – 2nd Join Point Model
74. Example Inter-type declarations • For example, if a programmer implemented the crosscutting display-update concern using visitors instead, an inter-type declaration using the visitor pattern might look like this in AspectJ: • This code snippet adds the acceptVisitor method to the Point class. • It is a requirement that any structural additions be compatible with the original class, so that clients of the existing class continue to operate, unless the AOP implementation can expect to control all clients at all times. 74 SEIV – AOD – AspectJ – 2nd Join Point Model
75. “Introduction” • An introduction is a member of an aspect, but it defines or modifies a member of another type (class). With introduction we can – add methods to an existing class – add fields to an existing class – extend an existing class with another – implement an interface in an existing class – convert checked exceptions into unchecked exceptions 75 SEIV – AOD – AspectJ – 2nd Join Point Model
76. “Introduction” Example aspect CloneablePoint { declare parents: Point implements Cloneable; declare soft: CloneNotSupportedException: execution(Object clone()); Object Point.clone() { return super.clone(); } } 76 SEIV – AOD – AspectJ – 2nd Join Point Model
77. “Introduction” 77 • Existing classes can be declared to implement an interface or extend a superclass. • Works as long as Java inheritance rules are not violated (no multiple inheritance). declare parents : [Type] implements [InterfaceList]; declare parents : [Type] extends [Class]; • Aspects can be made dependant only on a base type or interface. This makes aspects more reusable. SEIV – AOD – AspectJ – 2nd Join Point Model
78. Exception Softening 78 • Converts a checked exception into a runtime exception. • Sometimes it can be inconvenient to have to deal with checked exceptions. Involves a proliferation of try/catch blocks and throws clauses. Example: SQLException in JDBC API declare soft : SQLException : within(DatabaseAccess); • Exception is automatically rethrown as a org.aspectj.lang.SoftException SEIV – AOD – AspectJ – 2nd Join Point Model
79. Policy Enforcements 79 • Compile time and runtime enforcement. • In AspectJ it is possible to specify custom compile time warnings and errors using pointcuts. declare warning : get(* System.out) || get(* System.err) : “consider using Logger.log() instead”; declare error : set(public * *) || get(public * *) : “nonpublic access is not allowed”; • Runtime enforcement can be achieved through advice that detects policy violations. SEIV – AOD – AspectJ – 2nd Join Point Model
80. Syntax 80 • An aspect is: aspect nameOfAspect { body } – An aspect contains introductions, pointcuts, and advice • A pointcut designator is: when(signature) – The signature includes the return type – The “when” is call, handler, execution, etc. • A named pointcut designator is: name(parameters): pointcutDesignator • Advice is: adviceType(parameters): pointcutDesignator { body } • “Introductions” are basically like normal Java code SEIV – AOD – AspectJ – 2nd Join Point Model
81. Concluding Example 1 81 • aspect PointWatching { private Vector Point.watchers = new Vector(); public static void addWatcher(Point p, Screen s) { p.Watchers.add(s); } public static void removeWatcher(Point p, Screen s) { p.Watchers.remove(s); } • static void updateWatcher(Point p, Screen s) { s.display(p); } • pointcut changes(Point p): target(p) && call(void Point.set*(int)); after(Point p): changes(p) { Iterator iter = p.Watchers.iterator(); while ( iter.hasNext() ) { updateWatcher(p, (Screen)iter.next()); } } } SEIV – AOD – AspectJ – 2nd Join Point Model
82. Concluding Example 2 82 ObserverPattern is modular – all changes in single aspect – evolution is modular – it is easier to think about class Line extends Shape { 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; } } class Point extends Shape { 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; } } aspect ObserverPattern { private Display Shape.display; static void setDisplay(Shape s, Display d) { s.display = d; } pointcut change(Shape shape): this(shape) && (execution(void Shape.moveBy(int, int)) || execution(void Shape+.set*(*))); after(Shape shape): change(shape) { shape.display.update(s); } } SEIV – AOD – AspectJ – 2nd Join Point Model
83. Aspect Weaving 83 • An aspect weaver is a metaprogramming utility for aspect-oriented languages designed to take instructions specified by aspects (isolated representations of a significant concepts in a program) and generate the final implementation code. • The weaver integrates aspects into the locations specified by the software as a pre-compilation step. • By merging aspects and classes (representations of the structure of entities in the program), the weaver generates a woven class. SEIV – AOD – AspectJ – 2nd Join Point Model
84. Aspect Weaving (contd) 84 • Aspect weavers take instructions known as advice specified through the use of pointcuts and join points, special segments of code that indicate what methods should be handled by aspect code. • The implementation of the aspect then specifies whether the related code should be added before, after, or throughout the related methods. • By doing this, aspect weavers improve modularity, keeping code in one place that would otherwise have been interspersed throughout various, unrelated classes. SEIV – AOD – AspectJ – 2nd Join Point Model
85. Industry Adoption 85 • AOP adoption is happening very fast • Enterprise Java is most active domain – AspectWerkz, JBoss (JavaAssist), Spring, … – IBM actively using AspectJ in Websphere … – BEA, Oracle actively evaluating – Hot topic at TSS Symposium and JavaOne • And … – Danny Sabbah (IBM VP) commits to AOP in 3 of 5 main product lines – Gates says Microsoft will adopt AOP SEIV – AOD – AspectJ – 2nd Join Point Model
86. Remarks 86 • Aspect-oriented programming (AOP) is a new paradigm--a new way to think about programming • AOP is somewhat similar to event handling, where the “events” are defined outside the code itself • AspectJ is not itself a complete programming language, but an adjunct to Java • AspectJ does not add new capabilities to what Java can do, but adds new ways of modularizing the code • AspectJ is free, open source software • Like all new technologies, AOP may--or may not--catch on in a big way SEIV – AOD – AspectJ – 2nd Join Point Model
87. AOP Design Patterns • Director Design Pattern – You want to define a set of roles to be implemented by unknown sets of application classes so they can be interacted with generically by an abstract aspect. • Border Control Design Pattern – You want to formally define important regions within your application so your aspects can reuse those definitions to ensure they are only applied in the correct areas. • Policy Design Pattern – You want to define a set of development rules within a policy that can be applied to your application structure. 87 SEIV – AOD – AspectJ – Design Patterns
88. ASPECTJ Further Reading 88 SEIV – AOD – AspectJ – Books