日期:2014-05-17  浏览次数:21011 次

跟我学aspectj之七 ----- call,execution,within,withincode

本节开始,我们将详细介绍pointcut的语法

一、call和execution

   语法结构:execution([修饰符] 返回值类型 方法名(参数) [异常模式])  蓝色表示可选部分。

   例子:

  • execution(public *.*(..))  所有的public方法。
  • execution(* hello(..)) 所有的hello()方法
  • execution(String hello(..)) 所有返回值为String的hello方法。
  • execution(* hello(String))   所有参数为String类型的hello()
  • execution(* hello(String..)) 至少有一个参数,且第一个参数类型为String的hello方法
  • execution(* com.aspect..*(..))  所有com.aspect包,以及子孙包下的所有方法
  • execution(* com..*.*Dao.find*(..))  com包下的所有一Dao结尾的类的一find开头的方法   

    上面的几个例子,包括了修饰符,返回值,方法名,以及参数。大家可以根据需要灵活运用。接下来讲讲call 和 execution的区别,从字面理解:call为调用,而execution为执行。  事实上他们的区别也确实如此。

?

    call捕获的joinpoint是签名方法的调用点,而execution捕获的则是执行点。为了有说服力,我写了一个demo.代码如下:

?

?

?


我们拦截了参数为:int的main方法。 这里用到了一内置的对象:thisJoinPoint,他表示当前jionPoint. 跟我们在java中的this 其实是差不多的,如果你不明白,那么你多运行一下,好好体会一下。getSourceLocation()表示元代吗的位置:   我们运行一下HelloWorld.java。 结果如下:

?

?

?

14是行号,即:main(5);

?

接下来,我们把HelloAspect中的call改为execution。发现打印结果如下:

?

?

在比照一下代码,看下输出。  现在明白了吧??   一个是调用的地方,一个是执行的地方。

?

 thisJoinPoint.getSourceLocation() 这段代码将会在我们以后的Demo中经常用到。这是一个跟踪调试的好办法。

?

二、within 和 withincode

?

   现在假设你还有另外一个class,他也包含main()方法。

?

?

  我们的HelloAspect如下:

?

?

这样,便会把HelloAspectDemo的main方法捕获到,  现在leader说: HelloAspectDemo不需要捕获。那我们怎么办勒?你首先想到的肯定是修改pointcut,指定到我们的HelloWorld类。 这当然是可以的,假设:现在还有5个类,也有main方法,也需要拦截。那你这解决办法肯定就不行了。(当然你也可以用 || 来组合他们)。这个时候就用到了我们的within了。 修改一下HelloAspect

?

?