使用注解来创建切面是 AspectJ 5 所引入的关键特性。
我们前一篇已经定义了 Performance 接口,它是切面中切点的目标对象。
Q:如何定义切面?
A: 给出一个描述:如果一场演出没有观众的话,那就不能称之为演出。对不对?从演出的角度来看,观众是非常重要的,但是对演出本身的功能来将,它并不是核心,这是一个单独的关注点。因此,将观众定义为一个切面,并将其应用到演出上就是较为明智的做法。
之前需要在 build.gradle 导入 aspectjrt 包
// https://mvnrepository.com/artifact/org.aspectj/aspectjrt
compile group: 'org.aspectj', name: 'aspectjrt', version: '1.9.0.BETA-6'
package concert;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
/**
* 该类使用 @AspectJ 注解进行了标注。该注解表明该类不仅仅是一个 POJO,还是一个切面。
* 该类中的方法都使用注解来定义切面的具体行为。
*/
@Aspect
public class Audience {
//表演之前:将手机调至静音状态
@Before("execution(**concert.Performance.perform(..))")
public void silenceCellPhones() {
System.out.println("Silencing cell phones");
}
//表演之前:就座
@Before("execution(**concert.Performance.perform(..))")
public void takeSeats() {
System.out.println("Taking seats");
}
//表演之后:精彩的话,观众应该会鼓掌喝彩
@AfterReturning("execution(**concert.Performance.perform(..))")
public void applause() {
System.out.println("CLAP CLAP CLAP!!!");
}
//表演失败之后:没有达到观众预期的话,观众会要求退款
@AfterThrowing("execution(**concert.Performance.perform(..))")
public void demandRefund() {
System.out.println("Demanding a refund");
}
}
可以简化一下,使用 @Pointcut 注解。
package concert;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* 简化方案:@Pointcut 注解能够在一个 @AspectJ 切面内定义可重用的切点。
*/
@Aspect
public class Audience {
//通过在该方法上添加 @Pointcut 注解,我们实际上扩展了切点表达式语言,
//这样就可以在任何的切点表达式中使用 performance()了。
//该方法内容并不重要,实际上应该是空的。只是一个标识