AOP 之 6.6 通知参数

来源:互联网 发布:linux 启动进程 start 编辑:程序博客网 时间:2024/05/21 11:29

转自涛哥:http://jinnianshilongnian.iteye.com/blog/1420691

@Before(value="execution(* test(*)) && args(param)", argNames="param")  public void before1(String param) {      System.out.println("===param:" + param);  }  

切入点表达式execution(* test(*)) && args(param) :
1)首先execution(* test(*))匹配任何方法名为test,且有一个任何类型的参数;
2)args(param)将首先查找通知方法上同名的参数,并在方法执行时(运行时)匹配传入的参数是使用该同名参数类型,即java.lang.String;如果匹配将把该被通知参数传递给通知方法上同名参数。
其他指示符(除了execution和bean指示符)都可以使用这种方式进行参数绑定。
在此有一个问题,即前边提到的类似于【3.1.2构造器注入】中的参数名注入限制:在class文件中没生成变量调试信息是获取不到方法参数名字的。

所以我们可以使用策略来确定参数名:

1、如果我们通过“argNames”属性指定了参数名,那么就是要我们指定的;

@Before(value=" args(param)", argNames="param") //明确指定了  public void before1(String param) {      System.out.println("===param:" + param);  }  

2、如果第一个参数类型是JoinPoint、ProceedingJoinPoint或JoinPoint.StaticPart类型,应该从“argNames”属性省略掉该参数名(可选,写上也对),这些类型对象会自动传入的,但必须作为第一个参数;

@Before(value=" args(param)", argNames="param") //明确指定了  public void before1(JoinPoint jp, String param) {      System.out.println("===param:" + param);  }  

3、如果“class文件中含有变量调试信息”将使用这些方法签名中的参数名来确定参数名;

@Before(value=" args(param)") //不需要argNames了  public void before1(JoinPoint jp, String param) {      System.out.println("===param:" + param);  }  

4、如果没有“class文件中含有变量调试信息”,将尝试自己的参数匹配算法,如果发现参数绑定有二义性将抛出AmbiguousBindingException异常;对于只有一个绑定变量的切入点表达式,而通知方法只接受一个参数,说明绑定参数是明确的,从而能配对成功

@Before(value=" args(param)")  public void before1(JoinPoint jp, String param) {      System.out.println("===param:" + param);  }  

5、以上策略失败将抛出IllegalArgumentException。

0 0
原创粉丝点击