Aspect call execution

  call execution 的指示符分别为 call Method-Signature )、 execution Method-Signature ),匹配方法签名的方法或构造函数的执行。 对于 call 来说,调用的连接点位于方法调用点的调用代码处;对于 execution 来说,执行的连接点位于方法执行的位置。也就是说, call execution 的重要区别在于它们传递了哪些类型给 AspectJ 编译器以用来与 aspect 进行链接。

        通常,我们在使用 call execution 时,从效果上来看并不会觉察出二者的区别。下面给出一个例子说明 call execution 的运行时机及区别。

     

public   class  A  {
    
public   void  foo(){
        System.out.println(
" A.foo() " );
    }
}

public   class  Main {
    
public   void  callFoo(A a){
        a.foo();
    }
    
public   static   void  main(String[] args) {    
        Main m 
=   new  Main();
        m.callFoo(
new  A());
    }
}


        1 )现在我看一下下面使用 call 的切面:

                        Aspect call execution_第1张图片

 

   

           该切面定义了一个切入点 callA(Object o,Object t) ,其中 this (o) 表示将匹配的连接点的对象赋给 o target (t) 表示将匹配的连接点的目标对象赋给 t 。输出结果为:

 

           Aspect call execution_第2张图片

        

        输出表明, this 的类(调用类)为 Main target 的类(目标类)为 A 我们再看一下 Main 类:

 

       Aspect call execution_第3张图片


        在 AJDT 下,可以看到, call 切入点匹配的位置在调用类( Main )的方法 void callFoo(A a) 中,而不是在目标类 A 中。

        2 )再来看一下 execution 的例子:


       Aspect call execution_第4张图片


      Aspect call execution_第5张图片


        在这个方面中,切入点没有使用 this target ,而是在 before 通知中使用了 AspectJ API 达到同样的效果。可以看到,切入点 executionA() 匹配的连接点的位置在 A foo() 方法,这和上面的 call 匹配的连接点的位置是不同的。

       Aspect call execution_第6张图片

    

      

        从输出可以看到,在 execution 中, this target 指向同一个类 。在 call 中, this target 不是指向同一个类

        execution call 还有一点很重要的区别。对于继承类来说,如果它没有覆盖父类的方法,那么 execution 不会匹配子类中没有覆盖父类的方法。比如说我们有一个类 B 继承于 A ,但没有覆盖 A 类的 foo() ,那么对于 B 的实例的 foo() 方法, execution(* B.foo()) 将不会被匹配。

        做个总结,如果想跟踪连接点的内部代码运行情况可以考虑使用 execution ,但如果你只关心连接点的签名(比如你使用第三方库或是标准 API ),则使用 call

        注:该文参考了《 Eclipse AspectJ 》和《 AspectJ cookbook 》。

你可能感兴趣的:(Aspect call execution)