Spring AOP 五大通知类型

一、AOP 核心概念速览

在讲通知类型之前,先快速回顾几个基础概念,帮你建立整体认知:

  • 通知(Advice):增强逻辑本身,比如日志、异常处理,也就是你要 "插入" 到目标方法前后的代码。
  • 切入点(Pointcut):定义增强逻辑要插入到哪些目标方法上,通过表达式匹配。
  • 切面(Aspect):通知 + 切入点的组合,将增强逻辑切入到切入点的过程。

二、五大通知类型详解

Spring AOP 提供了 5 种通知类型,分别对应目标方法执行的不同阶段,我们用表格和场景来帮你区分:

通知类型 执行时机 特点 典型场景
前置通知(Before) 目标方法执行之前 目标方法出现异常,也不会执行后续流程 权限校验、参数日志打印
后置通知(After-Returning) 目标方法执行成功之后 目标方法出现异常,此通知不会执行 返回值处理、成功日志记录
异常通知(After-Throwing) 目标方法执行抛出异常之后 只有方法执行失败时才会触发 异常日志记录、异常告警
最终通知(After) 目标方法执行之后(无论成功 / 失败) 类似finally,方法无论执行结果如何都会执行 资源释放(关闭流、连接)
环绕通知(Around) 目标方法执行之前和之后 功能最强,可控制目标方法是否执行、修改参数和返回值 性能监控、事务控制、全局日志

三、通知类型代码示例(XML 配置版)

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 业务Bean -->
    <bean id="loginServer" class="com.qcby.LoginServer"/>

    <!-- 切面Bean -->
    <bean id="qx" class="com.qcby.QX"/>

    <!-- AOP配置 -->
    <aop:config>
        <aop:aspect ref="qx">
<!--            &lt;!&ndash; 前置通知 &ndash;&gt;-->
<!--            <aop:before method="beforeAdvice"-->
<!--                        pointcut="execution(public void com.qcby.LoginServer.login(..))"/>-->

<!--            &lt;!&ndash; 后置通知(方法成功执行后) &ndash;&gt;-->
<!--            <aop:after-returning method="afterReturningAdvice"-->
<!--                                 pointcut="execution(public void com.qcby.LoginServer.login(..))"/>-->

<!--            &lt;!&ndash; 异常通知(方法抛出异常时) &ndash;&gt;-->
<!--            <aop:after-throwing method="afterThrowingAdvice"-->
<!--                                pointcut="execution(public void com.qcby.LoginServer.login(..))"/>-->

<!--            &lt;!&ndash; 最终通知(无论成功失败都会执行) &ndash;&gt;-->
<!--            <aop:after method="afterAdvice"-->
<!--                       pointcut="execution(public void com.qcby.LoginServer.login(..))"/>-->

            <!-- 环绕通知(前后都能控制) -->
            <aop:around method="aroundAdvice"
                        pointcut="execution(public void com.qcby.LoginServer.login(..))"/>
        </aop:aspect>
    </aop:config>

</beans>

四、切入点表达式(execution)核心语法

切入点表达式是 AOP 的核心,也是新手最容易写错的地方,这里给你讲透固定写法和注意事项。

1. 固定语法格式

复制代码
execution(访问修饰符  返回值类型  包名.类名.方法名(参数列表))

2. 各部分说明

部分 说明 示例
访问修饰符 可省略不写 publicprivate
返回值类型 必填,不能省略不写 intString,通用写法用*(代表所有返回值类型)
包名 支持通配符*.. com.qcby.* 代表 qcby 包下所有子包;com.qcby.. 代表 qcby 包及所有后代包
类名 支持通配符* *Service 代表所有以 Service 结尾的类;* 代表所有类
方法名 支持通配符* add* 代表所有以 add 开头的方法;* 代表所有方法
参数列表 必填,支持通配符 (..) 表示任意类型和个数的参数;() 表示无参数;(int, String) 表示指定类型参数

3. 常见表达式示例

复制代码
// 示例1:匹配com.qcby.service包下所有类的所有方法
execution(* com.qcby.service.*.*(..))

// 示例2:匹配com.qcby包及所有子包下,所有类的所有方法
execution(* com.qcby..*.*(..))

// 示例3:匹配com.qcby.service包下UserService类的所有方法
execution(* com.qcby.service.UserService.*(..))

// 示例4:匹配com.qcby.service包下所有以add开头的方法
execution(* com.qcby.service.*.add*(..))

// 示例5:匹配com.qcby.service包下所有无参方法
execution(* com.qcby.service.*.*())

五、AOP 执行顺序总结

当一个方法被多个通知增强时,执行顺序如下:

  1. 环绕通知(前置部分)
  2. 前置通知
  3. 目标方法执行
  4. 后置通知(方法成功时)
  5. 异常通知(方法失败时)
  6. 最终通知
  7. 环绕通知(后置部分)
相关推荐
swipe12 分钟前
12|(前端转全栈)点击提交订单后,后端如何用事务守住价格、库存和订单?
前端·后端·面试
小林ixn16 分钟前
React + TypeScript 实战:从“类型体操”到“数据持久化”,一次讲透组件通信与副作用管理
前端·react.js·typescript
何时梦醒16 分钟前
React + TypeScript 企业级开发实战:从零搭建到组件架构演进
前端·react.js·全栈
Coffeeee17 分钟前
AGP9.0的主要变更项,给Gradle来一次大变样
android·前端·gradle
数聚天成DeepSData32 分钟前
外贸海关进出口数据去哪免费下载?从统计到明细的查找指南
linux·服务器·开发语言·前端·网络·人工智能·自然语言处理
SamDeepThinking36 分钟前
现场重构一段代码,展示什么叫「好代码,都在表达自己的意图」
java·后端·程序员
半夜里咳嗽的狼38 分钟前
组件进侧栏就变形?用 CSS Container Queries 把响应式边界收回组件
前端·css
xx240644 分钟前
前端性能优化笔记
前端·笔记·性能优化
带娃的IT创业者1 小时前
单文件架构的极致美学:深入解析 Bento 的 HTML 幻灯片技术实现
前端·架构·html·web开发·bento·单文件架构
小园子的小菜1 小时前
Java 并发四大工具类深度解析:CountDownLatch、CyclicBarrier、Semaphore、Exchanger 原理、源码与面试考点
java·开发语言·面试