一、注解使用
@EnableAspectJAutoProxy
相当于在bean.xml
中配置开启注解 AOP 的支持
<!-- 配置spring开启注解AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
切入点的设置表明了对哪些方法进行增强
/**
* 用于记录日志的工具类,它里面提供了公共的代码
*/
@Configuration
@ComponentScan("spring")
//不使用XML的配置方式
@EnableAspectJAutoProxy
//声明当前类为切面类
@Aspect
public class Logger {
@Pointcut("execution(* spring.service.impl.*.*(..))")
private void pt(){}
/**
* 前置通知
*/
@Before("pt()")
public void beforePrintLog() {
System.out.println("前置通知Logger类中的beforePrintLog方法开始记录日志了。。。");
}
/**
* 后置通知
*/
@AfterReturning("pt()")
public void afterReturningPrintLog() {
System.out.println("后置通知Logger类中的afterReturningPrintLog方法开始记录日志了。。。");
}
/**
* 异常通知
*/
@AfterThrowing("pt()")
public void afterThrowingPrintLog() {
System.out.println("异常通知Logger类中的afterThrowingPrintLog方法开始记录日志了。。。");
}
/**
* 最终通知
*/
@After("pt()")
public void afterPrintLog() {
System.out.println("最终通知Logger类中的afterPrintLog方法开始记录日志了。。。");
}
}
二、环绕通知
不过注解使用时,会存在一个问题,就是最终通知和后置通知的顺序会搞反:
解决办法就是换为环绕通知,也就是自己定义
/**
* 用于记录日志的工具类,它里面提供了公共的代码
*/
@Configuration
@ComponentScan("spring")
//不使用XML的配置方式
@EnableAspectJAutoProxy
//声明当前类为切面类
@Aspect
public class Logger {
@Pointcut("execution(* spring.service.impl.*.*(..))")
private void pt(){}
/**
* 环绕通知
*
* @param pjp
* @return
*/
@Around("pt()")
public Object aroundPringLog(ProceedingJoinPoint pjp) {
Object rtValue = null;
try {
//得到方法执行所需的参数
Object[] args = pjp.getArgs();
System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。前置");
//明确调用业务层方法(切入点方法)
rtValue = pjp.proceed(args);
System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。后置");
return rtValue;
} catch (Throwable t) {
System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。异常");
throw new RuntimeException(t);
} finally {
System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。最终");
}
}
}
三、多个增强类对同一个方法增强,设置增强类优先级
在增强类上面添加注解 @Order
(数字类型值),数字类型值越小优先级越高
@Component
@Aspect
@Order(1)
public class Logger