@Aspect //表示这是一个切面类 public class Audience { //使用简明的PointCut @Pointcut("execution(* com.service.Performance.perform(..))") public void performance(){} //前置通知 即 @Before("execution(* com.service.Performance.perform(..))") @Before("performance()") public void silenceCellPhones(){ System.out.println("Silencing cell phones"); } //前置通知 即 @Before("execution(* com.service.Performance.perform(..))") @Before("performance()") public void takeSeats(){ System.out.println("Taking seats"); } //方法调用结束通知(并不是指返回值通知,即使是void的返回值,仍然会触发通知) 即 @AfterReturning("execution(* com.service.Performance.perform(..))") @AfterReturning("performance()") public void applause(){ System.out.println("CLAP CLAP CLAP!!!"); } //有异常抛出的时候通知,即 @AfterThrowing("execution(* com.service.Performance.perform(..))") @AfterThrowing("performance()") public void demandRefund(){ System.out.println("Demanding a refund"); } }
View Code 2、启用AspectJ注解的自动代理有两种方式可以启用AspectJ 注解的自动代理:
(1)在 Java 配置文件中显示配置
@Configuration @EnableAspectJAutoProxy //启用Aop自动代理 public class JavaConfig { @Bean public Audience getAudience(){ return new Audience(); } }
View Code(2)在XML文件中配置
<!--启用AspectJ自动代理--> <aop:aspectj-autoproxy/> <bean id="audience" class="com.aspect.Audience"/>
View Code不管你是使用JavaConfig还是XML,AspectJ自动代理都会为使用@Aspect注解的bean创建一个代理,这个代理会围绕着所有该切面的切点所匹配的bean。当程序执行到连接点的时候,就会由代理转到切面触发相应的通知。
@Aspect public class Audience3 { @Pointcut("execution(* com.service.Performance.perform(..))") public void performance(){} @Around("performance()") public void watchPerformance(ProceedingJoinPoint joinPoint) { System.out.println("Silencing cell phones"); System.out.println("Taking seats"); try { joinPoint.proceed(); System.out.println("CLAP CLAP CLAP!!!"); } catch (Throwable throwable) { System.out.println("Demanding a refund"); throwable.printStackTrace(); } } }
View Code 注意 ProceedingJoinPoint 作为参数。这个对象是必须要有的,因为你要在通知中通过它来调用被通知的方法。当要将控制权交给被通知的方法时,它需要调用ProceedingJoinPoint的proceed()方法。