对于 call 来说,调用的连接点位于方法调用点的调用代码处
对于 execution 来说,执行的连接点位于方法执行的位置。
被调用者:
public class Callee { public void foo() { System.out.println("clalee.foo()"); } }
调用者: public class Caller { public void callFoo(Callee c) { c.foo(); } public static void main(String[] args) { new Caller().callFoo(new Callee()); } }
public aspect CallExecDemo { pointcut calls(Object o, Object t): call(* Callee.foo()) && target(t) && this(o);
pointcut exec(Object o, Object t): execution(* Callee.foo()) && target(t) && this(o);
其中this(o)表示将匹配的连接点的对象赋给o
target(t)表示将匹配的连接点的目标对象赋给t. before(Object oo, Object tt): calls(oo, tt){ System.out.println("call: this: " + oo); System.out.println("call: target: " + tt); } before(Object oo, Object tt): exec(oo, tt){ System.out.println("execution-->this: " + oo); System.out.println("execution-->target: " + tt); } }
> execution(void cn.xiaoyee.orient.Caller.main(String[])) call: this: cn.xiaoyee.orient.Caller@9db992 call: target: cn.xiaoyee.orient.Callee@1022de4 execution-->this: cn.xiaoyee.orient.Callee@1022de4 execution-->target: cn.xiaoyee.orient.Callee@1022de4 clalee.foo() < execution(void cn.xiaoyee.orient.Caller.main(String[]))
所以说:
对于 call 来说,调用的连接点位于方法调用点的调用代码处
对于 execution 来说,执行的连接点位于方法执行的位置。
引用:
在execution中,this和target指向同一个类。
在call中,this和target不是指向同一个类。
execution与call还有一点很重要的区别:
对于继承类来说,如果它没有覆盖父类的方法,那么execution不会匹配子类中没有覆盖父类的方法。
比如说我们有一个类B继承于A,但没有覆盖A类的foo(),那么对于B的实例的foo()方法,execution(* B.foo())将不会被匹配。
如果想跟踪连接点的内部代码运行情况可以考虑使用execution,但如果你只关心连接点的签名(比如你使用第三方库或是标准API),则使用call。