1 / 46

Aspect orientated programming

Explore the challenges of cross-cutting concerns in banking systems and how aspect-oriented programming can help address code scattering and duplication. Learn about common concerns like security/authentication, logging, and transaction handling.

mjenkins
Télécharger la présentation

Aspect orientated 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 orientatedprogramming COMP 319

  2. The problem • Code scattering class BankAccount { public void transfer(intamount,BankAccounttoAccount) { try { Log.transferringMoney(); if (authenticated(username,password) { // do transfer } } catch (TransactionExceptiontexc) { Log.storeExc(texc); } COMP319

  3. Concerns and Cross cut concerns • Concern examples, banking • Transfer between accounts • Product statement • Make billing payment • Cross cut concerns • Security/authentication • Logging • Transaction handling COMP319

  4. Cross cut concern problems • Scattering • Duplication • Code cloning • Tangling • Concerns not properly separated COMP319

  5. Cross cutting concern examples and approaches • Persistence • Object-relational mapping • Internationalization • Resource bundling • Code mobility • Pre-processing • Error handling • Chained exceptions, error return codes COMP319

  6. Definitions • Cross-cutting – Identify areas of code where common functionality exists • Advice – The code to be injected • Joinpoint – Where one or more aspects can be applied • Pointcut – A collection of joinpoints • Aspect – General term for where advice and point-cuts are combined COMP319

  7. Terminology • Weaving – Integrating applications and aspects (e.g. AspectJ is an “aspect weaver”) • Compile-time – Can produce integrated source-code, but typically only produces woven byte-code. • Run-time – Aspects are applied “on the fly” (typically when classes are loaded) COMP319

  8. AOP Platforms • AspectJ • Spring • JBoss AOP • AspectWerkz • Now working with AspectJ • Java Aspect Components (JAC) COMP319

  9. AspectJ • Now an Eclipse project (http://eclipse.org/aspectj/) • Developed at Xerox PARC • Released 2001 • Latest version (AspectJ 5) is a collaboration of AspectJ and AspectWerkz • AJDT - AspectJ Development Tools plug-in for Eclipse COMP319

  10. Aspect definition package com.aspect; public aspect DemoAspect { pointcut setterNotification() : call(* *.set*(..)); before() : setterNotification(){ System.out.println("setting data..."); } } Aspect Point-cut Advice COMP319

  11. Aspect example (Hello World) public class Main { public static void main(String[] args) { // TODO Auto-generated method stub hello(); } public static void hello() { System.out.println("Hello"); } } COMP319

  12. Aspect Example HelloWorld public aspect Hello { pointcuthelloCall() : execution( * Main.hello(..)); after() : helloCall() { System.out.println("World!!!"); } } COMP319

  13. Point cut definitions //call is the most common joinpoint type call([access modifier] returnType package.ClassName.method(args)); //Examples call(* *.*(..)); //Note: “..” is also a wildcard call(public * *.set*(..)); call(void *.set*(..)); call(* *.set*(int)); call(String com.foo.Customer.set*(..)); call(* com.foo.Customer+.set*(..)); //”+” cross-cuts children call(public void com..*.set*(int)); call(* *.set*(int, ..)); call(* *.set*(int, .., String)); COMP319

  14. Defining a pointcut • pointcut nameOfPointCut() : definition; • pointcut setters() :call(public * *.set*(..)); COMP319

  15. Types of Join point • call(method expr) • when a method is called • execution(method expr) • when a method is executed • handler(exception expr) • when a catch block is executed COMP319

  16. Join points public static void main(String argsv[]) { hello(); call } Public static void hello() { execution try { } catch (Exception e) { handler } } COMP319

  17. Types of Join points • get(field expr) • when a field is read • set(field expr) • when a field is set • pointcut settingLength() : set( int SetterMonitorExample.length); • staticinitialization(class expr) • when a static block of a class is executed COMP319

  18. Types of Join points • initialization(constructor expr) • when a constructor is executed • preinitialization(constructor expr) • when inherited constructors are executed • adviceexecution() • when an advice block is executed COMP319

  19. Adding Advice pointcuteveryCall() : call(* *.*(..)); before() : everyCall(){ System.out.println(“Advicecalled before method"); } after() : somePointCut(){ System.out.println("Advice called after each method"); } COMP319

  20. Anonymous point cuts in Advice before() : call(* *.*(..)) { System.out.println("Injecting advice..."); } // point cut doesn’t have name COMP319

  21. Types of Advice • before() • Before call or body • after() returning • after() throwing • after() • around() COMP319

  22. Types of Advice • after() returning [(type expr)] • called after normal execution of the joinpoint • after() throwing [(exception expr)] • called if the execution of the joinpoint throws the specified exception • after() • executes regardless (sort of like finally) COMP319

  23. Types of Advice • type around() [throws exception] • executes in place of a joint point of execution • You can stop or replace code execution • To call the original code, use proceed() COMP319

  24. Types of Advice • withincode(method expr) • true if joinpoint is within defined method • within(type expr) • true if joinpoint is within defined type (i.e. class definition) COMP319

  25. Exception handling in Advice • after() throwing • Intercepts at method level, before the catch() block • handler(exception type) • Intercepts at the catch() block • declare soft :exception type • Wraps any exception as a RuntimeException (which consequently no longer needs to be declared in the throws clause of the method) COMP319

  26. Exception handling advice before(java.io.FileNotFoundException exc) : handler(java.io.FileNotFoundException ) && args(exc) { System.out.println("Could not find file... message is "+exc.getMessage()); } COMP319

  27. Point cut operators • if(expr) • evaluate boolean expression • withincode(method expr) • true if joinpoint is within defined method • within(type expr) • true if joinpoint is within defined type COMP319

  28. Point cut operators • this(type expr) • true when joinpoint matches source object • target(type expr) • true when joinpoint matches target object • args(type expr) • true for any joinpoint matching argument type list COMP319

  29. Getting at the context • Sometimes we want to get at • The instance of this, which is being used at the point of call • The target instance • Example fred.getX(); // fred is the target • The arguments (x and y) • Example fred.setPosition(x,y) COMP319

  30. Getting the context • Declaring the context, type • before(BankAccount account) : • Declares the context type in the point cut, for example.. before(BankAccount account) : target(account) && authenticationNeeded() && (!execution(* BankAccount.authenticate(..))) { account.authenticate(); } • Question … Why do we have !execute(* BankAccount(authenticate()) COMP319

  31. Arguments example pointcut settingLength(int length) : set( int SetterMonitorExample.length) && args(length); void around(int inputLength) : settingLength1(inputLength) { System.out.println("Trying to set length to "+inputLength); if (inputLength<5) { proceed(inputLength); } else { System.out.println("Skipping length setting length too large"); } } COMP319

  32. Point cut logical operators • && • Logical AND • || • Logical OR • ! • Logical NOT COMP319

  33. thisJoinPoint thisJoinPoint.toString() thisJoinPoint.getKind() // call, execution, set, get thisJoinPoint.getSignature(); System.out.println("thisJoinPoint.getSourceLocation(): " + thisJoinPoint.getSourceLocation(); // source code line number thisJoinPoint.getTarget(); // target object thisJoinPoint.getThis(); // source object COMP319

  34. thisJointPoint example package testaspect; public class AspectReflectionExample { public void greet() { Greeter greeter=new Greeter("Seb"); greeter.greet("Hello "); } public static void main(String argvs[]) { AspectReflectionExampleinstance=new AspectReflectionExample(); instance.greet(); } } COMP319

  35. thisJointPoint example package testaspect; public class Greeter { private String name=""; public void goodMorning() { System.out.println("Good morning "+name); } public void greet(String message) { System.out.println(message+name); } public Greeter(String name) { this.name=name; } } COMP319

  36. thisJoinPoint example package testaspect; public aspect ReflectAspect { pointcut greetings(Greeter example) : call(* *.Greeter.greet(..)) && target(example); before(Greeter example) : greetings(example) { System.out.println("this: " + this); System.out.println("thisJoinPoint.toString(): " + thisJoinPoint.toString() ); System.out.println("thisJoinPoint.getKind(): " + thisJoinPoint.getKind() ); System.out.println("thisJoinPoint.toLongString(): " + thisJoinPoint.toLongString() ); System.out.println("thisJoinPoint.toShortString(): " + thisJoinPoint.toShortString() ); System.out.println("thisJoinPoint.getClass(): " + thisJoinPoint.getClass() ); System.out.println("thisJoinPoint.getSignature(): " + thisJoinPoint.getSignature() ); System.out.println("thisJoinPoint.getSourceLocation(): " + thisJoinPoint.getSourceLocation() ); System.out.println("thisJoinPoint.getTarget(): " + thisJoinPoint.getTarget() ); System.out.println("thisJoinPoint.getThis(): " + thisJoinPoint.getThis() ); } } COMP319

  37. thisJoinpoint this: testaspect.ReflectAspect@3a3ee284 thisJoinPoint.toString(): call(void testaspect.Greeter.greet(String)) thisJoinPoint.getKind(): method-call thisJoinPoint.toLongString(): call(public void testaspect.Greeter.greet(java.lang.String)) thisJoinPoint.toShortString(): call(Greeter.greet(..)) thisJoinPoint.getClass(): class org.aspectj.runtime.reflect.JoinPointImpl thisJoinPoint.getSignature(): void testaspect.Greeter.greet(String) thisJoinPoint.getSourceLocation(): AspectReflectionExample.java:6 thisJoinPoint.getTarget(): testaspect.Greeter@37dd7056 thisJoinPoint.getThis(): testaspect.AspectReflectionExample@2afa3ac1 COMP319

  38. Modifying target classes • Inter type declarations • Aspect can add methods, field and constructors to external class aspect SecurityChecks booleanBankAccount.authenticated=false; publicvoidBankAccount.authenticate() { if (authenticated) return; // TO DO more authentication code } public BankAccount.new(String password,String name, String pin) { } } COMP319

  39. Modifying target classes • You can also use inter-type declarations to change the inheritance, to add new interface or new super class • New parent must be sub-class of existing parent public aspect ChangeStructure { declare parents: BankAccount implements Serializable; declare parents: BankAccount extends SecureObject; } COMP319

  40. Intertype declarations, compile control • declare parent • declare warning • Compiler warnings result from joinpoints • declare error • Compiler errors result from joinpoints • declare precedence • Define aspect precedence COMP319

  41. Encouraging logging, using warnings • Simple example • From Matt Chapman, AJDT Committer public aspect EnforceLogging{ pointcut scope(): within(*); pointcut printing(): get(* System.out) || get(* System.err) || call(* Throwable+.printStackTrace()); declare warning : scope() && printing(): "don't print, use the logger"; } COMP319

  42. Class watcher example • Monitors all calls to setters • If data changes • Dirty flag=true • Application can use this to • Save data only if dirty flag=true, saves unrequired writes • Data can be discarded from cache if dirty flag=false • Supports lazy writing caches • Help data integraty testing COMP319

  43. Watcher Example public aspect WatchSetters { // just to invoke test code below public static void main(String[] args) { Client.handleTimer(new Timer()); } private static final Class[] GETTER_ARG_TYPES = new Class[]{}; private static final Object[] GETTER_ARGS = new Object[]{}; private static final Object NONE = new Object(); public interface IWatched {} /** true if new value sent to any setter */ private boolean IWatched.dirty; /** false if unable to maintain dirty b/c no privileges, no getter... */ private boolean IWatched.dirtyValid = true; /** clients can use dirty flag */ public boolean IWatched.isDirty() { return dirty; } /** clients handle case when dirty flag is invalid */ public boolean IWatched.isDirtyValid() { return dirtyValid; } COMP319

  44. Watcher example (Pointcut) • public pointcut setters(IWatched watched) : target(watched) && execution(void IWatched+.set*(*)); // advice uses args[0] COMP319

  45. Watch timer advice void around(IWatched watched) : setters(watched) && if (watched.dirtyValid) { // get value by invoking getter method Object value = NONE; // no valueString getterName=“”;try { getterName = "g" + thisJoinPoint.getSignature().getName().substring(1); Method method = watched.getClass() .getMethod(getterName, GETTER_ARG_TYPES); value = method.invoke(watched, GETTER_ARGS); } catch (Throwable t) { } ; if (NONE == value) { watched.dirtyValid = false; proceed(watched); return; } // compare value with arg being set - pointcut has exactly 1 parm Object arg = thisJoinPoint.getArgs()[0]; if (!(null == arg ? value == null : arg.equals(value))) { proceed(watched); watched.dirty = true; } } COMP319

  46. Watcher Example Persistence if (!(null == arg ? value == null : arg.equals(value))) { proceed(watched); watched.dirty = true; String tableName=thisJoinPoint.getTarget().getClass().getName(); tableName=tableName.replace(".", "_"); String sql="update "+tableName+" set "+getterName.substring(3)+"='"+arg.toString()+"' where id='"+watched.id+"'"; System.out.println("sql : "+sql); } COMP319

More Related