1 / 38

Aspect Oriented Programming

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”. Accounting. XML Parsing. Logging. Database. Crosscutting Concerns.

ryder-ward
Download Presentation

Aspect Oriented Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Motivation for AOP • Typical programs often have behavior that doesn't fit into a single module. • “Code Tangling” Accounting XML Parsing Logging Database

  3. 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.

  4. 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.

  5. AspectJ Example public 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 here The message has been delivered. Hello! The message is: AspectJ rocks The message has been delivered.

  6. 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.

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

  8. 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.

  9. 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.

  10. AspectJ – Capturing Context 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

  11. 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.

  12. 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 }

  13. 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.

  14. AspectJ – Kinded pointcuts • Kinded pointcuts capture exposed join points. Join point category Pointcut syntax

  15. 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.

  16. 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) args() this() target()

  17. 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

  18. 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()); } } }

  19. 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); }

  20. AspectJ – Method result caching public 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 cache 1 added to cache 2 added to cache 6 added to cache 24 added to cache 120 added to cache Result: 120 120 retrieved from cache Result: 120

  21. 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.

  22. AspectJ – Abstract aspect example 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; } }

  23. 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.

  24. Introduction – Mixin style inheritance public 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()); } }

  25. Default interface implementation public 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()); } }

  26. 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.

  27. 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

  28. 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”.

  29. 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.

  30. 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.

  31. 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.

  32. CLOS – Method combination • Applicable generic methods are combined into a single effective method. (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) Output: A pie is about to be cooked A food is about to be cooked Cooking a pie A food has been cooked A pie has been cooked

  33. 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

  34. JAsCo – Stateful aspects class 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(); }

  35. 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. Employee public class Employee { string name; int salary; } fred.salary = 200; causes transparent update

  36. Case study – JDO • Uses advice to add side effects to field access. • Weaving is done by the JDO bytecode enhancer. javac Employee.java Employee.class JDO bytecode enhancer (Aspect weaver) mapping.xml enhanced Employee.class

  37. 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.

  38. 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.

More Related