在Spring开发中,凡是「和业务目标无关,但又几乎每个接口/方法都会用到」的逻辑,都可以使用 AOP(切面)进行开发。下面结合 Spring Boot + 微服务 + Redis总结一下AOP 使用清单。
一、最常见 & 最值得做成切面的
1 接口防抖 / 限流
典型特征
-
和业务无关
-
每个接口都可能要
-
策略可变
切面处理的事
-
解析用户身份
-
生成 key
-
Redis / Sentinel / Guava 控制频率
扩展方向:
-
防抖(时间窗内只允许一次)
-
限流(QPS / 次数)
-
黑名单 / 灰度
2 接口幂等
防止"同一请求被执行多次"
使用场景
-
下单
-
支付回调
-
MQ 消费
-
表单提交
注解示例:
java
@Idempotent(key = "#requestId", expire = 10)
切面做的事
-
从参数 / header 中取唯一标识
-
Redis
SETNX -
已存在直接返回结果或报错
和防抖的区别
| 防抖 | 幂等 |
|---|---|
| 控制时间 | 控制唯一性 |
| 多次点击 | 多次重试 |
3 统一日志(接口 / 方法级)
典型痛点
-
每个接口都写日志
-
日志格式不统一
-
排查问题靠猜
切面能力
java
@Around("@annotation(ApiLog)")
能做什么
-
入参
-
返回值
-
耗时
-
用户信息
-
traceId
常见玩法
-
请求日志
-
慢接口告警
-
关键业务审计日志
4. 权限 & 鉴权(比拦截器更精细)
java
@RequiresPermission("order:create")
为什么用 AOP 而不是 Interceptor
-
Interceptor 只能拿 URL
-
AOP 能拿方法、注解、参数
切面里可以做
-
校验 token
-
校验角色 / 权限
-
动态 RBAC
5. 参数校验增强(业务校验)
JSR-303 是"格式校验",但很多是业务校验
java
@CheckOrderStatus(allow = {CREATED})
切面里:
-
查数据库
-
校验状态流转是否合法
-
不合法直接抛异常
比散落在 service 里清爽得多
6. 分布式锁(极其适合 AOP)
java
@DistributedLock(
key = "#orderId",
expire = 5,
waitTime = 1
)
切面逻辑:
-
加锁
-
执行业务
-
finally 解锁
常见实现
-
Redis
-
Redisson
7. 事务增强(条件事务 / 手动回滚)
java
@CustomTransactional
切面里:
-
动态决定是否开启事务
-
捕获异常决定是否回滚
在复杂业务编排中很有用
二、进阶:微服务体系里的 AOP
8. 接口降级 & 熔断(业务级)
java
@Fallback(method = "defaultResult")
切面中:
-
try 执行业务
-
catch 异常
-
自动走兜底逻辑
比 try-catch 散落一地高级太多
9. 接口调用链追踪(TraceId)
java
@Trace
切面:
-
生成 traceId
-
放入 MDC
-
自动贯穿日志 / RPC
排查线上问题神器
10. MQ 消费统一处理
java
@MqConsume
切面中:
-
防重复消费
-
异常重试
-
失败入库 / 告警
三、什么时候「不适合」用切面
以下情况别硬用 AOP
| 场景 | 原因 |
|---|---|
| 核心业务流程 | 可读性差 |
| 极端性能敏感 | 有额外开销 |
| 逻辑强依赖返回值 | 调试困难 |
| 需要明确执行顺序 | 容易踩坑 |
四、总结
AOP 最适合做的事情:
"删掉它,业务还能跑;
但没有它,系统会很难维护。"