注解创建切面是AspectJ5引入的关键特性,AspectJ面向注解的模型可以非常简便的通过少量注解把任意类转变为切面。
1.定义切面
package com.vclog.mainsite.app.controller.aspect; import org.aspectj.lang.annotation.*; /** * Created by hu on 2018-03-28. */ @Aspect public class Audience { @Before("execution(public * com.vclog.mainsite.app.controller..*.*(..))") public void doBefore(){ System.out.println("表演之前,就坐"); } @Around("execution(public * com.vclog.mainsite.app.controller..*.*(..))") public void doAround(){ System.out.println("表演中,欣赏"); } @AfterReturning("execution(public * com.vclog.mainsite.app.controller..*.*(..))") public void doAfter(){ System.out.println("表演之后,回家"); } @AfterThrowing("execution(public * com.vclog.mainsite.app.controller..*.*(..))") public void doAfterErr(){ System.out.println("表演失败之后,骂天骂地"); } }
Audience类使用@AspectJ注解进行了标注,该注解表明Audience不仅仅是一个POJO,还是一个切面。Audience类中的方法都使用注解来定义切面的具体行为。
Audience有四个方法,定义了一个观众在观看演出可能会做出的事情,可以看到,这些方法都使用了通知注解来表明它们应该在什么时候调用。AspectJ提供了五个注解来定义通知,如下表所示:
Audience使用到了后面四个注解,doBefore( ) 方法使用到了@Before注解,表明应该在演出开始之前调用。doAround( ) 方法使用到了@Around注解,表明应该在演出中调用。doAfter( ) 方法使用到了@AfterReturning注解,它会在演出成功返回后调用。doAfterErr( ) 方法使用到了@AfterThrowing注解,这表明它会在抛出异常以后调用。
通过看前面的代码,你可能已经发现。所有的这些注解都给定了一个切点表达式作为它的值,同时,这四个方法的切点表达式都是相同的。其实,他们可以设置成不同的切点表达式。相同的切点表达式我们重复了四遍,感觉不是很明智,这里我们可以引入切点的概念@Pointcut。
package com.vclog.mainsite.app.controller.aspect; import org.aspectj.lang.annotation.*; /** * Created by hu on 2018-03-28. */ @Aspect public class Audience { @Pointcut("execution(public * com.vclog.mainsite.app.controller..*.*(..))") public void action(){ } @Before("action()") public void doBefore(){ System.out.println("表演之前"); } @Around("action()") public void doAround(){ System.out.println("表演中"); } @AfterReturning("action()") public void doAfter(){ System.out.println("表演之后"); } @AfterThrowing("action()") public void doAfterErr(){ System.out.println("表演失败之后"); } }在Audience中,action( ) 方法使用了@Pointcut注解。为@Pointcut注解设置的值是一个切点表达式,就像之前在通知注解上所设置的那样。通过在action( ) 方法上添加@Pointcut注解,实际上扩展了切点表达语言,这样就可以在任何的切点表达式中使用action( )。