2017년 6월 7일 수요일

Programming in AspectJ

https://en.wikipedia.org/wiki/AspectJ

http://www.eclipse.org/aspectj/docs.php

1. Method and field pointcuts allow wildcards in Java signatures
 - method signature grammar:
  1) signature -> Modifier (Return type) Class Method name "(" Parameters ")" ("throws" Exception)
   e.g. public int java.util.List.size()

 - each syntax element can be the corresponding Java syntax element or a wildcard

 - AspectJ uses different wildcards
  1) plain(*): matches any Java syntax elements in the same context
   e.g. public * *(int) => any public method with one integer argument

  2) lexical(*): matches names as in egular expressions
   e.g. * *set*(int) => any method with one integer argument and a name that contains "set"

  3) list ellipsis(..): matches arbitrary parameter lists
   e.g. * * *(int, ..) => any method with any number of arguments but at least one integer

  4) sub-type(+): matches arbitrary sub-types of the given base type
   e.g. Figure+.new() => any constructor for Figure or any of its sub-classes

 http://howtodoinjava.com/spring/spring-aop/writing-spring-aop-aspectj-pointcut-expressions-with-examples/


2. Method and field pointcuts allow signature-based access
 - call(Signature): every call to any method or constructor matching Signature at the call site
 - execution(Signature): every execution of any method or constructor matching Signature
 !! call and execution can behave differently with inheritance
  : call uses the call site vs. execution uses the declaration site
  : If you want to pick a join point that runs when an actual piece of code runs, use execution, but if you want to pick one that runs when a particular signature is called, use call

http://perfspy.blogspot.co.uk/2013/09/differences-between-aspectj-call-and.html

http://stackoverflow.com/questions/18132822/execution-vs-call-join-point

 - get(Signature): every reference to any field matching Signature
 - set(Signature): every assignment to any field matching Signature


3. State-based pointcuts allow instance checks and context access
 - TypeOrID argument must have defined type: type pattern or identifier introduced by advice
  e.g. target(FigureElement+)
       before(FigureElement fe): target(fe)
 - this(TypeOrID): matches when the current object is an instance of the specified type
 - target(TypeOrID): matches when the target object is an instance of the specified type
 !! target is the object to which the current join point transfers control; it may be different to this at a method call join point
  e.g. before(Line l): call(* Line.*(..)) && this(l) => calls to Line-methods sent from a Line-object l
       before(Line l): call(* Line.*(..)) && this(Line) => calls to Line-methods

http://stackoverflow.com/questions/34305792/this-vs-target-aspectj

 - args(TypeOrID): matches when the arguments are instances of the specified types


4. Return values can be accessed via after / returning
 - return values are not yet available when identifiers are bound at join point
  ... but only after method execution
  e.g. after(Line l) returning(Point p): call(* *.get*(*)) && args(l) { }

 - similar for exceptions: throwing

http://stackoverflow.com/questions/5656554/getting-a-return-value-or-exception-from-aspectj


5. around-advice allows to change the base program's behaviour completely
 - before / after only add befaviour to join point (incremental changes)
 - around replaces original join point behaviour (invasive changes)
  1) advice return type must be compatible with join point return type
 - proceed() invokes original joinpoint behaviour
  1) uses original arguments to join points
  2) returns original join point result
  3) under control of advice code
  4) proceed() can have arguments
   int around(int i): call(int C.*(*, int)) && args(Object, i) {
       int j = proceed(i*2);
       return j/2;
   }


6. Program text-based pointcuts expose static program scopes
 - within(Type): matches when the code executing is defined within the declaration of one of the matching types
 - withincode(Method): matches when the code executing is defined within the declaration of any method matching the signature


7. org.aspectj.lang contains meta-classes to expose the pointcut
http://www.eclipse.org/aspectj/doc/next/progguide/language-thisJoinPoint.html

http://www.programcreek.com/java-api-examples/index.php?api=org.aspectj.lang.JoinPoint


8. Control flow-based pointcuts expose dynamic program scopes
 - cflow(PCD): mathces all joinpoints in the control flow of any joinpoint P that matches the given pointcur desciptor PCD
 - cflowbelow(PCD): matches all joinpoints in the control flow of any joinpoint P that matches the given PCD, except P itself
 - cflow does not distribute over &&
   cflowbelow distribute over ||
 - access the most recent call context
 http://maverick-amey.blogspot.co.uk/2007/12/using-cflow-and-cflowbelow-in-pointcuts.html


9. Inter-type declarations modify the static program structure
 - can add members to existing classes / interfaces
 public aspect LineLabeling {
     private String Line.label = "";
     public void Line.setLabel(String s) {
         label = s;
     }
     public String Line.getLabel(){
         return label;
     }
 }
 ! Visibility Rules for inter-type member declarations
  1) private: members visible only in declaring aspect
  2) public: visibility relative to aspect's package
  3) inter-type: can see aspect methods and cannot see aspect fields
   => in advice, you can use methods, not fields

 - can introduce new classes / interfaces
 public aspect Labeling {
     public class Labels extends FigureElements {
         private String Line.label = "";
         public void Line.setLabel(String s) {
             label = s;
         }
         public String Line.getLabel(){
             return label;
         }
     }
     declare parents (Line || Point) extends Labels;
 }

 - can extend inheritance relation
 public aspect Labeling {
     interface Labels {} // marker interface
     private String Labels.label = "";
     public void Labels.setLabel(String s) {
         label = s;
     }
     public String Labels.getLabel(){
         return label;
     }
     declare parents (Line || Points || Compound) extends Labels
 }

 - can declare warnings / errors
 public aspect FactoryCheck {
     pointcut illegalNew(): call(FigureElement+.new(..)) && !withincode(* FigureElementFactory.mk*(..));
     declare error: illegalNew() {
         "Use factory method";
     }
 }

https://eclipse.org/aspectj/doc/next/adk15notebook/ataspectj-itds.html

댓글 없음:

댓글 쓰기