@Configuration
@ComponentScan
@EnableAspectJAutoProxy // 启用自动代理
public class ConcertConfig {
@Bean
public Audience audience() {
return new Audience();
}
@Bean
public Performance singer() {
return new Singer();
}
} 现在可以进行简单的测试:
public class AOPTest {
@Test
public void test() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ConcertConfig.class);
Performance performance = applicationContext.getBean("singer", Performance.class);
performance.perform();
}
} 控制台输出:
2.5、创建环绕通知
通过@Around注解创建环绕通知:
@Aspect
public class Audience {
@Pointcut("execution(* concert.Performance.perform(..))") // 定义命名的切点
public void performance() {
}
@Around("performance()") // 环绕通知
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Silencing cell phones");
System.out.println("Taking seats");
jp.proceed(); // 通知目标对象的被通知方法
System.out.println("CLAP CLAP CLAP!!!");
} catch (Throwable throwable) {
System.out.println("Demanding a refund");
throwable.printStackTrace();
}
}
} 需要通过调用ProceedingJoinPoint参数的proceed()方法来调用被通知的方法。否则实际上会阻塞对被通知方法的调用。 2.6、处理通知中的参数
切面可以获取传递给被通知方法的参数并做相应操作。
比如在上面的示例中,Audience切面类可以记录歌手唱了多少首歌:
Performance.java:
public interface Performance {
public void perform(int num);
} Singer.java:
public class Singer implements Performance{
public void perform(int num) {
System.out.println("歌手唱了"+num+"首歌~~");
}
} Aspect.java:
@Aspect
public class Audience {
private int num; // 记录歌手唱了多少首歌