Spring Annotation(AOP篇)
本文主要简单了解一下使用Java annotation的情况下,先介绍一下比较主流和简单的用法,Spring对AspectJ的支持。在ApplicationContext中加入关于AOP的命名空间,具体内容见Spring 使用AspectJ来配置AOP.首先明确一点,用作通知(Advice)的类也应该受到ApplicationContext的管理,之后再使用AspectJ的标签来管理通知动作,见代码:
//import ... @Component @Aspect public class Alert { @Before("execution(* get*(..))")//方法运行前通知 public void show() { System.out.println("before"); } @After("execution(* get*(..))")//最终通知 public void show2() { System.out.println("after"); } @Pointcut("execution(* get*(..))") public void afterReturn(){} //方法返回值通知,注意这个通知需要与@Pointcut配合使用 @AfterReturning(pointcut="afterReturn()",returning="value") public void returning(Object value){ System.out.println("returning"); } @AfterThrowing(pointcut="afterReturn()",throwing="ex") //异常通知,这个通知复用了afterReturn的pointcut。当然你也可以使用新的pointcut public void doRecoveryActions(Exception ex){ //... } @Around("afterReturn()") //环绕通知。真正的方法实际上是joinPoint.proceed(); public Object doSomeForAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("before around"); Object retVal=joinPoint.proceed(); System.out.println("after around"); return retVal; } }
这段代码的意思就是在所有以get开头的方法被调用之前和之后都会执行show和returning,show2方法,其运行顺序是 show(),returning(),show2()。注意*与get*之间有一个空格。对一个方法,你可以同时使用Before Advice,Around Advice,AfterReturning Advice,After Advice,Throwing Advice。那么这些通知的顺序是什么呢?一个方法运行时,最先触发的是Around Advice,之后是Before Advice 是 AfterReturning(如果有的话),之后是After Advice,最后还要再通知Around。
就拿上面代码这个例子说,打印的顺序是:
before around before returning after after around
下面着重介绍一下除了execution之外的其他类型的pointcut。
within:within指的是在某个范围内所有的方法执行。
例如:
@pointcut(“within(com.xyz.project.web..*)”)就是指在com.xyz.project.web包及其子包中所有的方法被执行的时候,都会触发这个pointcut。within(com.xyz.project.web.*)这样写就只是针对这个包,而不包括这个包的子包。
this:this指的是实现了某个确定的接口的代理对象中的方法被执行。
target:target指的是实现了某个确定的接口的代理对象中的方法被执行。