Aspect Oriented Development

88
Aspect Oriented Development Viraj Brian Wijesuriya [email protected] 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

Transcript of Aspect Oriented Development

Aspect Oriented Development

Viraj Brian Wijesuriya

[email protected]

1

SCS 4120 - Software Engineering IV

BACHELOR OF SCIENCE HONOURS IN COMPUTER SCIENCEBACHELOR OF SCIENCE HONOURS IN SOFTWARE ENGINEERING

All in One Place Lecture NotesDistribution Among Friends Only

All copyrights belong to their respective owners

• 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

• 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!

SEIV – AOD – Introduction

4

The Problem!

• 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?

• 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

• 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

• 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

• 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

SEIV – AOD – Introduction

10

A Typical Application

Accounting

ATM

Database

System

Persistence Logging

Business Logic

Concern

Persistence

LoggingImplementation

modules

Accounting

ATM

Database

System

Persistence

Logging

• 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

• 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

• 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

• 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

• 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

• 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

• 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

• 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

SEIV – AOD – Introduction

19

Traditional Implementation of CC

Accounting Module

ATM Module

Database Module

Logging Module

API

invocations

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

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

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

– 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

SEIV – AOD – Introduction

24

Example Application

a simple drawing application (JHotDraw)

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)

*

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+

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

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

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)

*

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

SEIV – AOD – Introduction

31

Aspect Oriented Dev Stages

Business

Logic

Security

Logging

Persistence

Identify

concerns

Integrating all

concerns

• 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!

SEIV – AOD – Introduction

33

Aspect Dev Stages Explained!

Aspect Decomposition

Aspects Core program

Aspect Recomposition

Requirements

Final System

• 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?

• 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

• 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

• 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

• 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

SEIV – AOD – AspectJ – 1st Join Point Model

39

Example Program 1Public class Logging{//classpublic void check( ) {

System.out.println("Inside Logging Class Method"); }}

public class ATM { //classpublic 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 { //Aspectpointcut callPointcut( ) : call(void ATM.foo(int, String)); //Pointcutbefore( ) : callPointcut( ) { //Advice

System.out.println( “I am from Log aspect"); Logging logg= new Logging();logg.check(); } }

Name of Pointcut

beforeafteraround

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

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.

SEIV – AOD – AspectJ – 1st Join Point Model

42

Capture Context Examplepublic 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

• 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

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

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

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

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

• 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 PointsSEIV – AOD – AspectJ – 1st Join Point Model

• 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

PointcutsSEIV – AOD – AspectJ – 1st Join Point Model

• 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

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

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

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

Primitive Pointcuts- call, execution- get, set- handler- initialization, staticinitialization

- within, withincode

- this, target, args

- cflow, cflowbelow

54

SEIV – AOD – AspectJ – 1st Join Point Model

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

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

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

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

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

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

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

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

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

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

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

Advice Example 1public 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

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

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

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

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

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

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

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

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

“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

“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

“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

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

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

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

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

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

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

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

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

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

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

ASPECTJ Further Reading

88

SEIV – AOD – AspectJ – Books