这篇写的不错 Spring AOP
- 首先引入需要的 jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 定义一个切面类
/**
*操作日志,切面处理类
* @author dxayga
* @Aspect 作用是把当前类标识为一个切面供容器读取
* @Component 交给 spring 管理
*/
@Aspect
@Component
public class LogAspect {
}
- 定义一个切入点和 @Pointcut 的用法
对于注解的用法可以看看这篇 @Pointcut 详解
最常用的两个表达式 execution 和 @annotation
- execution
execution(modifier-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern))
modifier-pattern? :访问修饰符匹配,如public 表示匹配公有方法
ret-type-pattern :返回值类型匹配,* 表示任何返回值,全路径的类名等
declaring-type-pattern? :类路径匹配
name-pattern :方法名匹配,* 代表所有,set*,代表以set开头的所有方法
param-pattern :参数匹配
如 @Pointcut("execution(public * com.cork.service.SysRoleService.list(..))")
@Pointcut("execution(public * com.cork.service.SysRoleService.list(..))")
public void logPointCut(){
}
- annotation
首先写一个注解 自定义注解
@Pointcut("@annotation(com.cork.annotation.Log)")
public void logPointCut(){
}
- 接下来就是定义通知 Advice
@Before 在切点方法之前执行
@After 在切点方法之后执行
@AfterReturning 切点方法返回后执行
@AfterThrowing 切点方法抛异常执行
@Around 属于环绕增强,能控制切点执行前,执行后,,用这个注解后,程序抛异常,会影响@AfterThrowing这个注解
@Pointcut("@annotation(com.cork.annotation.Log)")
public void logPointCut(){
}
@Before("logPointCut()")
public void before(JoinPoint point) throws Throwable{
log.info("前置通知");
}
@After("logPointCut()")
public void after(JoinPoint point) throws Throwable{
log.info("后置通知");
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable{
log.info("环绕通知前");
Object proceed = point.proceed();
log.info("环绕通知后");
return proceed;
}
@AfterReturning("logPointCut()")
public void afterReturning(JoinPoint point){
log.info("返回值后通知");
}
@AfterThrowing("logPointCut()")
public void afterThrowing(JoinPoint point){
log.info("发生异常后通知");
}
要注意的是环绕通知的 ProceedingJoinPoint.proceed() 方法,代表调用目标方法和返回值