spring aop 的五种通知类型
- 前置通知 before advice:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常
- 后置通知 after returning advice:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行
- 异常通知 after throwing advice:在连接点抛出异常后执行
- 最终通知 after (finally) advice:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容
- 环绕通知 around advice:环绕通知围绕在连接点前后,能在方法调用前后自定义一些操作,还需要负责决定是继续处理 join point (调用 proceedingjoinpoint 的 proceed 方法)还是中断执行
五大通知类型中,环绕通知功能最为强大,因为环绕通知,可以控制目标方法是否执行。
如果需要记录异常信息,使用异常通知。
其他通知,只能做记录工作,不能做处理,所以执行顺序其实对整个程序影响不大,没有必要太深究。
spring aop 通知类型使用
添加 aspect 切面类
package com.example.demo.module.aspect;
import org.aspectj.lang.joinpoint;
import org.aspectj.lang.proceedingjoinpoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.component;
@component
@aspect
public class advicetest {
// 配置织入点
@pointcut("execution(public * com.example.demo.module.aspect.test.*(..))")
public void test(){
}
@before("test()")
public void dobefore(joinpoint joinpoint){
system.out.println(joinpoint.getsignature().getname() + "执行前置通知---");
}
@afterreturning("test()")
public void doaftersuccess(joinpoint joinpoint){
system.out.println(joinpoint.getsignature().getname() + "执行返回通知---");
}
@afterthrowing("test()")
public void doaftererror(joinpoint joinpoint){
system.out.println(joinpoint.getsignature().getname() + "执行异常通知---");
}
@around(value = "test()", argnames = "pjp")
public object doaround(proceedingjoinpoint pjp) {
object[] args = pjp.getargs();
object result;
try {
// before
system.out.println(pjp.getsignature().getname() + "环绕前置通知---");
result = pjp.proceed(args);
// afterreturning
system.out.println(pjp.getsignature().getname() + "环绕返回通知---");
}catch (throwable e){
// afterthrowing
system.out.println(pjp.getsignature().getname() + "环绕异常通知---");
throw new runtimeexception(e);
}finally {
// after
system.out.println(pjp.getsignature().getname() + "环绕最终通知---");
}
return result;
}
@after("test()")
public void doafter(joinpoint joinpoint){
system.out.println(joinpoint.getsignature().getname() + "执行最终通知---");
}
}
添加测试方法:
package com.example.demo.module.aspect;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
@requestmapping("test")
@restcontroller
public class test {
@getmapping("testmethod")
public void testmethod(){
system.out.println("方法执行---");
}
}
运行结果:

测试异常通知,修改测试方法:
package com.example.demo.module.aspect;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
@requestmapping("test")
@restcontroller
public class test {
@getmapping("testmethod")
public void testmethod(){
int i= 1/0;
system.out.println("方法执行---");
}
}
运行结果:

通知执行顺序
spring 版本不一样,通知执行顺序可能也会存在差异
@before、@after、@afterreturning、@afterthrowing执行顺序
- spring 4.0
正常情况:@before -> 目标方法 -> @after -> @afterreturning
异常情况:@before -> 目标方法 -> @after -> @afterthrowing- spring 5.28
正常情况:@before -> 目标方法 -> @afterreturning -> @after
异常情况:@before -> 目标方法 -> @afterthrowing -> @after
@around的执行顺序
- spring 4.0
正常情况:环绕前置 -> 目标方法执行 -> 环绕返回 -> 环绕最终
异常情况:环绕前置 -> 目标方法执行 -> 环绕异常 -> 环绕最终- spring 5.28
正常情况:环绕前置 -> 目标方法执行 -> 环绕返回 -> 环绕最终
异常情况:环绕前置 -> 目标方法执行 -> 环绕异常 -> 环绕最终
五大通知执行顺序
- spring 4.0
正常情况:环绕前置 -> @before -> 目标方法执行 -> 环绕返回 -> 环绕最终 -> @after -> @afterreturning
异常情况:环绕前置 -> @before -> 目标方法执行 -> 环绕异常 -> 环绕最终 -> @after -> @afterthrowing- spring 5.28
正常情况:环绕前置 -> @before -> 目标方法执行 -> @afterreturning -> @after -> 环绕返回 -> 环绕最终
异常情况:环绕前置 -> @before -> 目标方法执行 -> @afterthrowing -> @after -> 环绕异常 -> 环绕最终
到此这篇关于spring aop 五种通知类型小结的文章就介绍到这了,更多相关spring aop 通知类型内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论