跟我学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.代码如下:

package com.aspectj.demo.test;

public class HelloWorld {

	
	public static void main(int i){
		System.out.println("in the main method  i = " + i);
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		main(5);
	}

}

package com.aspectj.demo.aspect;



public aspect HelloAspect {

	pointcut HelloWorldPointCut() : call(* main(int));
	
	
	
   before() : HelloWorldPointCut(){
	  System.out.println("Entering : " + thisJoinPoint.getSourceLocation());
	}
}

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


Entering : HelloWorld.java:14
in the main method  i = 5
14是行号,即:main(5);

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

Entering : HelloWorld.java:6
in the main method  i = 5

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


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


二、within 和 withincode 

   

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

package com.aspectj.demo.test;

public class HelloAspectDemo{
	
	
	public static void main(String[] args) {
		System.out.println("Hello aspectj");
	}
}

  我们的HelloAspect如下:

package com.aspectj.demo.aspect;



public aspect HelloAspect {

	pointcut HelloWorldPointCut() : execution(* main(..));
	
	
	
   before() : HelloWorldPointCut(){
	  System.out.println("Entering : " + thisJoinPoint.getSourceLocation());
	}
}

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

 

package com.aspectj.demo.aspect;

import com.aspectj.demo.test.HelloAspectDemo;



public aspect HelloAspect {

	pointcut HelloWorldPointCut() : execution(* main(..)) && !within(HelloAspectDemo);
	
	
	
   before() : HelloWorldPointCut(){
	  System.out.println("Entering : " + thisJoinPoint.getSourceLocation());
	}
}

  再运行一下HelloAspectDemo,你会发现他被排除了,也就是说他没有被拦截到。  

  withincode与within相似,不过withcode()接受的signature是方法,而不是类。用法,意思都差不多,只不过是使用场合不同。



  在接下来的一章,我将给大家介绍aspectj中最难理解的一个概念:控制流(cfow() cfowbelow())。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值