/* understanding control flow versus withincode point cuts */ public class CFLOWS { public static void f(int x) { System.out.println("f, x is "+x); g(x); } public static void g(int x) { System.out.println("g, x is "+x); h(x+2); } public static void h(int x) { System.out.println("h, x is "+x); } public static void main(String[] args) { f(1); } } aspect A { // the following advice takes effect when h is called under the // dynamic context of f: before() : call(void CFLOWS.h(int)) && cflow(call(void CFLOWS.f(int))) { System.out.println("advice1 before "+thisJoinPoint); } // the following advice will not be executed, since statically // there is no call to h from the body of f. before() : call(void CFLOWS.h(int)) && withincode(void CFLOWS.f(int)) { System.out.println("advice2 before "+thisJoinPoint); } // The following will be executed since there's a call to h from g before() : call(void CFLOWS.h(int)) && withincode(void CFLOWS.g(int)) { System.out.println("advice3 before "+thisJoinPoint); } } // difference between cflow and withincode (and within) is that // withincode is static, cflow is dynamic // What would happen if we had an advice like: // before() : cflow(public static void *.main(..)) { ... } // ??? // This pointcut picks out all join points in the entire program!! // Both withincode and cflow (and if) are examples of *property-based* // pointcuts. They should only be used in conjunction with *signature-based* // pointcuts such as call(..) and execution(..), since they pick out much // more specific join points.