}
切入点表达式execution(* test(*)) && args(param) :
(1)首先execution(* test(*))匹配任何方法名为test,且有一个任何类型的参数;
(2)args(param)将首先查找通知方法上同名的参数,并在方法执行时(运行时)匹配传入的参数是使用该同名参数类型,即java.lang.String;如果匹配将把该被通知参数传递给通知方法上同名参数。
参数匹配的策略
1:可以通过“argNames”属性指定参数名 ,示例如:
java代码:
查看复制到剪贴板打印
@Before(value=" args(param)", argNames="param") //明确指定了
public void before1(String param) {
System.out.println("===param:" + param);
}
2:如果第一个参数类型是JoinPoint、ProceedingJoinPoint或JoinPoint.StaticPart类型,应该从“argNames”属性省略掉该参数名(可选,写上也对),这些类型对象会自动传入的,但必须作为第一个参数 。示例如:
java代码:
查看复制到剪贴板打印
@Before(value=" args(param)", argNames="param") //明确指定了
public void before1(JoinPoint jp, String param) {
System.out.println("===param:" + param);
}
3:如果“ class文件中含有变量调试信息”,Spring将可以使用这些方法签名中的参数名来确定参数名,示例如下:
java代码:
查看复制到剪贴板打印
@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。
处理参数
java代码:
查看复制到剪贴板打印
@Around("execution(List
"com.xyz.SystemArchitecture.inDataAccessLayer() && " + "args(accountHolderNamePattern)")
public Object preProcessQueryPattern(ProceedingJoinPoint pjp, String accountHolderNamePattern)
throws Throwable {
String newPattern = preProcess(accountHolderNamePattern);
return pjp.proceed(new Object[] {newPattern});
}
获取方法运行后的返回值
java代码:
查看复制到剪贴板打印
@AfterReturning(
pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
Advice执行的顺序
如果有多个通知想要在同一连接点运行会发生什么?Spring AOP 的执行通知的顺序跟AspectJ的一样。 在“进入”连接点的情况下,最高优先级的通知会先执行(所以上面给出的两个前置通知(before advice)中,优先级高的那个会先执行)。 在“退出”连接点的情况下,最高优先级的通知会最后执行。只需要记住通知是按照定义的顺序来执行的就可以了。
当定义在 不同的 切面里的两个通知都需要在一个相同的连接点中运行,那么除非你指定,否则执行的顺序是未知的。 你可以通过指定优先级来控制执行顺序。在Spring中可以在切面类中实现 org.springframework.core.Ordered 接口做到这一点。 在两个切面中,Ordered.getValue() 方法返回值较低的那个有更高的优先级。
java代码:
查看复制到剪贴板打印
声明一个切面 :
...
...
声明一个切入点 :
在切面里面声明一个切入点和声明一个顶级的切入点非常类似:
java代码:
查看复制到剪贴板打印
...
当需要连接子表达式的时候,'&'在XML中用起来非常不方便,所以关键字'and', 'or' 和 'not'可以分别用来代替'&', '||' 和 '!'。
java代码:
查看复制到剪贴板打印
声明通知Advice,Before Advice
method="doAccessCheck"/>
...
返回后通知(After returning advice)
method="doAccessCheck"/>
...
java代码:
查看复制到剪贴板打印
抛出异常后通知(After throwing advice)
thowing="dataAccessEx"
method="doRecoveryActions"/>
...
后通知(After (finally) advice)
method="doReleaseLock"/>
...
Around通知
java代码:
查看复制到剪贴板打印
method="doBasicProfiling"/>
...
通知的参数,可以通过 arg-names 属性来实现
java代码:
查看复制到剪贴板打印