格格来闯关
113.36M · 2026-02-04
文章内容收录到个人网站,方便阅读:hardyfish.top/
AOP(Aspect-Oriented Programming,面向切面编程)解决的是一类“横切关注点”问题。
这些逻辑不属于任何一个核心业务用例,却几乎散落在所有用例周围,例如日志、权限、事务、坚控、幂等等。
把它们从业务代码里抽离出来,集中声明、统一织入(weaving),业务代码就能保持干净、稳定,治理策略也更可控。
AOP 的典型应用场景(按工程收益排序)
1)统一日志与审计(Audit)
log.info();字段口径一致,便于检索与风控。典型切点:
2)鉴权、登录态与数据权限
注意边界:
3)事务管理与一致性边界
@Transactional 本质就是 AOP 代理在方法边界开启/提交/回滚事务。常见陷阱(影响实际效果):
public 方法生效(常见默认代理策略下)。4)性能坚控与链路追踪(Metrics/Tracing)
5)异常治理与统一错误码
说明:Web 层的统一异常处理常由 @ControllerAdvice 完成;AOP 更适合 Service/RPC 方法边界的异常策略。
6)幂等、限流、熔断与重试(Resilience)
实现方式:
7)参数校验与契约约束
if 判断;失败策略统一(错误码、提示语、日志级别)。补充:Java 常用 Bean Validation(JSR 380)在 Controller/Service 也可通过 AOP 触发与增强。
8)缓存(Cache Aside)与防穿透
注意:缓存与业务一致性强相关,AOP 更适合“可容忍短暂不一致”的读多写少场景;强一致要更谨慎。
在项目中应用 AOP 的落地方式(从设计到上线)
1)先定“切面边界”:在哪一层织入
常用选择:
边界选择原则:
2)用注解表达意图,用 Pointcut 表达范围
落地基本套路是“自定义注解 + 切点表达式”:
@Audit、@Idempotent、@RateLimit。示例(概念级):
@Pointcut("@annotation(com.xxx.Audit)")@Around("execution(* com.xxx..service..*(..)) && @annotation(audit)")这样做的好处是范围可控,避免“一刀切”拦截导致性能与副作用问题。
3)选对 Advice 类型:Around/Before/AfterThrowing
工程上常见组合:
@Around@Before 或 @Around@AfterThrowing 或 @Around4)把“横切逻辑”做成可配置组件,而不是硬编码
可配置点通常包括:
配置来源:
@ConfigurationProperties5)处理好顺序与嵌套:@Order 与事务/重试/幂等的关系
多个切面叠加时,“谁包住谁”会改变语义:
在 Spring 中常用:
@Order 或实现 Ordered 控制切面优先级(数值越小优先级越高)。6)避免 AOP 的常见坑(影响生产效果)
-parameters 或借助调试信息;否则审计字段提取困难。7)一套可复用的“项目级 AOP 套件”长什么样
常见的可落地组合:
AuditAspect:注解驱动,抽取业务 ID、操作者、动作类型,写审计表或消息。MetricAspect:方法级耗时与异常率,打点到 Prometheus/Micrometer。IdempotentAspect:基于 Redis 的幂等 key + TTL + 并发互斥策略。PermissionAspect:权限点校验 + 数据范围注入(ThreadLocal 或参数增强)。MaskingAspect:日志脱敏,按字段规则处理(手机号、身分证、token)。配套约束:
RequestContext)承载 traceId、tenantId、operatorId。适用边界:什么时候不该用 AOP
一个落地小案例(文字版)
在“创建订单”场景里常见组合是:
Controller:生成 traceId、记录访问日志、入参脱敏。
Service createOrder():@Idempotent 保证重复提交不重复下单;@Transactional 保证订单与库存扣减原子;
@Audit 记录“用户创建订单”的审计事件;MetricAspect 记录耗时与异常。外部支付调用:在支付 Client 方法上织入 Retry/CircuitBreaker,并记录第三方调用耗时与错误码。
这样业务代码只保留“下单这件事”的关键路径,治理策略集中在切面里,变更也集中发生。