aspect oriented programming michael kucera cas 706 march 15, 2005

38
Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Upload: harvey-mccoy

Post on 25-Dec-2015

220 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Aspect Oriented Programming

Michael Kucera

CAS 706

March 15, 2005

Page 2: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Motivation for AOP• Typical programs often have behavior that

doesn't fit into a single module.• “Code Tangling”

XML Parsing

Accounting

Database

Logging

Page 3: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Crosscutting Concerns• AOP addresses behaviors that span many, often

unrelated, modules.

• Core Concerns:– Primary core functionality.– Central functionality of a module.

• Crosscutting Concerns:– System wide concerns that span multiple modules.– Cuts across the typical division of responsibility.

• OOP creates a coupling between core and crosscutting concerns.

• AOP aims to modularize crosscutting concerns.

Page 4: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Aspects• 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.

Page 5: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ Examplepublic class Example {

public static void deliverMessage(String message) {System.out.println("The message is: " + message);

}

public static void main(String [] args) {deliverMessage("I'm here");deliverMessage("AspectJ rocks");

}}

public aspect ExampleAspect {

pointcut helloPC() : call(void Example.deliverMessage(..));

before() : helloPC() {System.out.print("Hello! ");

}

after() : helloPC() {System.out.println("The message has been delivered.");

}}

Output:

Hello! The message is: I'm hereThe message has been delivered.Hello! The message is: AspectJ rocksThe message has been delivered.

Output:

Hello! The message is: I'm hereThe message has been delivered.Hello! The message is: AspectJ rocksThe message has been delivered.

Page 6: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Weaving• 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.

Page 7: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Overview• Join point

– Places where crosscutting concerns can be woven in.– Ex. method call, field access, object creation.

• Pointcut– Declaration that selects join points and collects

contexts at that point.

• Advice– Code to be executed at a join point.– Three types: before, after and around.

• Aspect– Unit of modularity.– Can contain fields and methods like a regular Java

class.

Page 8: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Overview• Introduction

– Introduces changes to classes.– Makes static changes that alone do not effect be

behavior of the system.– Can add methods and fields to a class.– Add implemented interfaces.– Adds mixin like inheritance to Java.

• Compile time declaration– Add compile time errors and warnings upon detecting

certain usage patterns.

• Every valid Java program is a valid AspectJ program.

Page 9: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Join 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.

Page 10: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Capturing Contextpublic 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

Output:

Salary: 100000

Page 11: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

What about encapsulation?• AOP breaks encapsulation in a controlled

manner.• Encapsulation is broken between classes and

aspects.• Aspects marked as privileged have access to

the private members of a class.• Encapsulation is preserved between classes.

• An aspect encapsulates a crosscutting concern.

Page 12: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ - Pointcuts• 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

}

Page 13: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ - Pointcuts• 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.

Page 14: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Kinded pointcuts• 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

Page 15: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – 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().

• cflowbelow can be used to select non-recursive calls.

Page 16: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Pointcuts that capture context• 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()

Page 17: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Advice• Advice is a method like construct that expresses

the action to be taken at the join points that are captured by a pointcut.

• Before advice– executes prior to the join point

• After advice– executes following the join point

• Around advice– surrounds the join point’s execution– can continue original execution, bypass execution or

cause execution with an altered context– can cause execution of the join point multiple times

Page 18: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Around advice

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());

}}

}

Page 19: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – After advice• Executes after the execution of a join point.• Can distinguish between normal returns and

those that throw an exception.

after() returning : call(* Account.*(..)) {System.out.println(“Successful return”);

}

after() throwing : call(* Account.*(..)) {System.out.println(“Failure”);

}

after() throwing(RemoteException ex) : call(* *.*(..)) {System.out.println(“Exception “ + ex +

“ while executing “ + thisJoinPoint);}

Page 20: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Method result cachingpublic class Factorial {

public static long factorial(int n) {if(n == 0) return 1;return n * factorial(n - 1);

}public static void main(String[] args) {

System.out.println("Result: " + factorial(5));System.out.println("Result: " + factorial(5));

}}

public aspect FactorialOptimizeAspect {private Map cache = new HashMap();pointcut factorialOp(int n) : call(long *.factorial(int)) && args(n);

long around(int n) : factorialOp(n) {Object value = cache.get(new Integer(n));

if(value == null) return proceed(n);

System.out.println(value + " retrieved from cache");return ((Long)value).longValue();

}

after(int n) returning(long result) : factorialOp(n) {if(cache.put(new Integer(n), new Long(result)) == null) System.out.println(result + " added to cache");

}}

Output:1 added to cache1 added to cache2 added to cache6 added to cache24 added to cache120 added to cacheResult: 120120 retrieved from cacheResult: 120

Output:1 added to cache1 added to cache2 added to cache6 added to cache24 added to cache120 added to cacheResult: 120120 retrieved from cacheResult: 120

Page 21: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – 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.

Page 22: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Abstract aspect examplepublic 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 overridepublic pointcut logPoints() : call(* *.factorial(..));

public Logger getLogger() {return Logger.global;

}}

Page 23: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

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.

Page 24: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Introduction – Mixin style inheritancepublic interface Tagable {

void setTag(String tag);String getTag();

}

public aspect TagAspect {private String Tagable.tag;

public String Tagable.getTag() {return tag;

}

public void Tagable.setTag(String tag) {this.tag = tag;

}

declare parents : Employee implements Tagable;

before(Tagable t) : target(t) && !within(TagAspect) {t.setTag(thisJoinPoint.toString());

}

after(Tagable t) : target(t) && !within(TagAspect){System.out.println(t.getTag());

}}

Page 25: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Default interface implementationpublic interface Tagable {

public void setTag(String tag);public String getTag();

static aspect Implementation {private String Tagable.tag;

public void Tagable.setName(String tag) { this.tag = tag;}public String Tagable.getName() { return tag;}

}}

public class Example implements Tagable {

public static void main(String[] args) {Example ex = new Example();ex.setTag(”It works”);System.out.println(”Tag: ” + ex.getTag());

}}

Page 26: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Modifying the class hierarchy• 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.

Page 27: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

AspectJ – Exception softening• 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

Page 28: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Policy Enforcement• Mechanism for ensuring that system components

follow certain programming practices.• For example; enforce that public access to

instance variables is prohibited.• Avoid incorrect usages of an API.• Ensures better quality.• In AOP policy enforcement concerns can be

implemented in aspects.• Aspect based policy enforcement is reusable.• AOP can be used for “Design by Contract”.

Page 29: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Policy Enforcement in AspectJ• 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.

Page 30: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Aspect precedence• It is possible for more than one piece of advice

to apply to a join point.• It may be important to control the order in which

advice is applied.

declare precedence : Aspect1, Aspect2, ... ;

• In the absence of any specified precedence control, the order in which the advice is applied is non-deterministic (at compile time).

• If more than one piece of advice in the same aspect applies to a pointcut, then the advice that comes first in the file has precedence.

Page 31: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Aspect association• Typically an aspect represents a singleton object

(aspect instance) that is instantiated by the system.

• It may be useful to have more than one instance of an aspect in the system. Can create associations between aspect instances and other objects.

• Can associate a new aspect instance with a target object by using a pointcut.

public aspect CacheAspect perthis(access()) { .. }

• Alternatively can use introduction.

Page 32: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

CLOS – Method combination

(defclass food () ())(defclass pie (food) ())

(defmethod cook ((p pie)) (print "Cooking a pie."))

(defmethod cook :before ((f food)) (print "A food is about to be cooked."))

(defmethod cook :after ((f food)) (print "A food has been cooked."))

(defmethod cook :before ((p pie)) (print "A pie is about to be cooked."))

(defmethod cook :after ((p pie)) (print "A pie has been cooked."))

(setq pie-1 (make-instance 'pie))(cook pie-1)

• Applicable generic methods are combined into a single effective method.

Output:

A pie is about to be cookedA food is about to be cookedCooking a pieA food has been cookedA pie has been cooked

Output:

A pie is about to be cookedA food is about to be cookedCooking a pieA food has been cookedA pie has been cooked

Page 33: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

JAsCo – An aspect oriented language• Emphasizes aspect reuse.• In AspectJ pointcuts are hardcoded... less reuse.• JAsCo allows adding, altering and removing

aspects while the program is running.• Supports runtime weaving and unweaving.• Aspect beans:

– Contain hooks: abstract pointcut definitions together with advice

• Connectors:– used to deploy reusable aspect beans– explicitly specify the way aspect beans are combined

Page 34: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

JAsCo – Stateful aspectsclass LoggerBean {

hook LogHook {

LogHook(startmethod(..args1), runningmethod(..args2), stopmethod(..args3)) {

start > pc1; pc1: execution(startmethod) > pc3 || pc2; pc3: execution(stopmethod) > pc1; pc2: execution(runningmethod) > pc3 || pc2; }

before pc2 (){ System.out.println(”executing: ” + calledmethod.getName()); }

} }

static connector testconnector { LoggerBean.LogHook hook1 = new LoggerBean.LogHook(* *.*.start(*), * *.doIt(*), * *.*.stop(*));

LoggerBean.LogHook hook2 = new LoggerBean.LogHook(* *.*.login(*), * *.shop(*), * *.*.logout(*));

hook1.before(); // optional hook2.before();}

Page 35: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Case study – JDO• JDO (Java Data Objects) is a “transparent

persistence” framework for Java.• Allows the manipulation of the state of an object

to transparently update a database.

public class Employee { string name; int salary;}

Name Salary

Fred 100 200

Biff 150

Employee

fred.salary = 200; causes transparent update

Page 36: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Case study – JDO• Uses advice to add side effects to field access.• Weaving is done by the JDO bytecode enhancer.

Employee.java javacjavac Employee.class

mapping.xmlJDO bytecode

enhancer (Aspect weaver)

JDO bytecode enhancer

(Aspect weaver)

enhanced Employee.class

Page 37: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

Conclusion• AOP has many potential benefits.• Higher modularization.• Cleaner responsibilities for individual modules.• Improved separation of concerns.• Easier system evolution. Much easier to add

crosscutting functionality.• More code reuse.• Can make code easier or harder to understand.• Already starting to become mainstream (JBoss,

JDO, Spring).• Like any new technology, AOP can be abused.

Page 38: Aspect Oriented Programming Michael Kucera CAS 706 March 15, 2005

References• Laddad, Ramnivas. AspectJ in Action. Greenwich, Conn.: Manning

Publications, 2003.

• Lesiecki, Nicholas. “Improve modularity with aspect oriented programming”. IBM Developerworks, January,2002. Available online at http://www-106.ibm.com/developerworks/java/library/j-aspectj.

• Marshall, Joe. “Warp Speed Introduction to CLOS”. Available online at http://home.comcast.net/~prunesquallor/guide.html.

• Vanderperren, W., Suvee, D., Cibran, M. and De Fraine, B. Stateful Aspects in JAsCo. In proceedings of SC 2005, LNCS, April 2005

• Eclipse AspectJ plug-in, http://eclipse.org/aspectj.