当前位置: 首页 > news >正文

Spring AOP(二) Spring AOP 完整指南

Spring AOP(二)Spring AOP 完整指南

  • Spring AOP 完整指南
    • 一、`@Around` 切入点表达式大全
      • 常用切入点表达式表格
    • 二、`execution` 表达式详解(最强大)
      • 语法格式
      • 常用示例表格
      • 通配符说明
    • 三、组合表达式
    • 四、Spring AOP 五种通知类型
      • 完整对比表格
    • 五、各通知类型代码示例
      • 1. `@Around` - 环绕通知(最强大)
      • 2. `@Before` - 前置通知
      • 3. `@AfterReturning` - 后置返回通知
      • 4. `@AfterThrowing` - 异常通知
      • 5. `@After` - 最终通知
    • 六、执行顺序对比
      • 正常执行流程
      • 异常执行流程
    • 七、实战案例:完整的切面
    • 八、选择建议
    • 九、注意事项

Spring AOP 完整指南

一、@Around切入点表达式大全

常用切入点表达式表格

表达式说明示例
@annotation(注解名)匹配标注了某个注解的方法@annotation(authCheck)
execution(...)匹配方法执行(最常用)execution(* com.example.service.*.*(..))
within(包或类)匹配指定包或类中的所有方法within(com.example.service.*)
this(类型)匹配代理对象是指定类型的方法this(com.example.service.UserService)
target(类型)匹配目标对象是指定类型的方法target(com.example.service.UserService)
args(参数类型)匹配方法参数符合类型的方法args(java.lang.String, ..)
@within(注解)匹配标注了某个注解的类中的所有方法@within(org.springframework.stereotype.Service)
@target(注解)匹配目标对象标注了某个注解的方法@target(org.springframework.stereotype.Controller)
@args(注解)匹配方法参数标注了某个注解的方法@args(com.example.annotation.Sensitive)
bean(bean名称)匹配指定名称的 Beanbean(userService)

二、execution表达式详解(最强大)

语法格式

execution(修饰符? 返回类型 方法名(参数) throws 异常?)

常用示例表格

表达式说明
execution(public * *(..))所有 public 方法
execution(* set*(..))所有以 “set” 开头的方法
execution(* com.example.service.*.*(..))service 包下所有类的所有方法
execution(* com.example.service..*.*(..))service 包及其子包下所有方法
execution(* com.example.service.UserService.*(..))UserService 类的所有方法
execution(public User com.example.service.UserService.getById(..))精确匹配 getById 方法
execution(* *(java.lang.String))只有一个 String 参数的方法
execution(* *(.., java.lang.String))最后一个参数是 String 的方法
execution(* *(java.util.List, ..))第一个参数是 List 的方法
execution(* com.example.service.*.*(..)) && !execution(* *.delete*(..))service 包所有方法,排除 delete 开头

通配符说明

通配符含义
*匹配任意字符(一个)
..匹配多个包、多个参数
+匹配子类

三、组合表达式

运算符说明示例
&&与(同时满足)execution(* com.example.service.*.*(..)) && @annotation(authCheck)
||或(满足其一)@annotation(authCheck) || @annotation(loginCheck)
!非(不满足)!execution(* *.delete*(..))

四、Spring AOP 五种通知类型

完整对比表格

通知类型注解执行时机能否控制方法执行典型应用场景
环绕通知@Around方法执行前后✅ 能(通过proceed()权限校验、事务管理、性能监控
前置通知@Before方法执行❌ 不能日志记录、参数校验
后置通知@AfterReturning方法成功返回后❌ 不能处理返回值、缓存更新
异常通知@AfterThrowing方法抛出异常后❌ 不能异常处理、告警通知
最终通知@After方法执行完成后(无论成功或失败)❌ 不能资源释放、清理工作

五、各通知类型代码示例

1.@Around- 环绕通知(最强大)

@Around("@annotation(authCheck)")publicObjectdoAround(ProceedingJoinPointjoinPoint,AuthCheckauthCheck)throwsThrowable{System.out.println("=== 前置处理 ===");// 执行原方法Objectresult=joinPoint.proceed();System.out.println("=== 后置处理 ===");returnresult;}

2.@Before- 前置通知

@Before("@annotation(authCheck)")publicvoiddoBefore(JoinPointjoinPoint,AuthCheckauthCheck){// 获取方法名StringmethodName=joinPoint.getSignature().getName();System.out.println("即将执行方法: "+methodName);// 获取参数Object[]args=joinPoint.getArgs();System.out.println("参数: "+Arrays.toString(args));}

3.@AfterReturning- 后置返回通知

@AfterReturning(value="@annotation(authCheck)",returning="result")publicvoiddoAfterReturning(JoinPointjoinPoint,Objectresult){System.out.println("方法执行成功,返回值: "+result);// 可以修改返回值(但不推荐)if(resultinstanceofBaseResponse){((BaseResponse<?>)result).setMessage("操作成功");}}

4.@AfterThrowing- 异常通知

@AfterThrowing(value="@annotation(authCheck)",throwing="exception")publicvoiddoAfterThrowing(JoinPointjoinPoint,Throwableexception){StringmethodName=joinPoint.getSignature().getName();System.err.println("方法 "+methodName+" 执行失败: "+exception.getMessage());// 记录错误日志、发送告警等log.error("方法 {} 执行异常",methodName,exception);}

5.@After- 最终通知

@After("@annotation(authCheck)")publicvoiddoAfter(JoinPointjoinPoint){// 无论成功还是失败都会执行System.out.println("方法执行完成,进行资源清理");}

六、执行顺序对比

正常执行流程

@Around 前置处理 ↓ @Before 前置通知 ↓ 执行原方法 ↓ @AfterReturning 后置返回通知 ↓ @After 最终通知 ↓ @Around 后置处理

异常执行流程

@Around 前置处理 ↓ @Before 前置通知 ↓ 执行原方法(抛出异常) ↓ @AfterThrowing 异常通知 ↓ @After 最终通知 ↓ @Around 捕获异常(可选)

七、实战案例:完整的切面

@Aspect@Component@Slf4jpublicclassLogAspect{@Around("@annotation(logAnnotation)")publicObjectaround(ProceedingJoinPointjoinPoint,LoglogAnnotation)throwsThrowable{longstartTime=System.currentTimeMillis();try{// @Before 的逻辑log.info("开始执行方法: {}",joinPoint.getSignature().getName());// 执行原方法Objectresult=joinPoint.proceed();// @AfterReturning 的逻辑longendTime=System.currentTimeMillis();log.info("方法执行成功,耗时: {}ms",endTime-startTime);returnresult;}catch(Throwablee){// @AfterThrowing 的逻辑log.error("方法执行失败: {}",e.getMessage(),e);throwe;}finally{// @After 的逻辑log.info("方法执行完成");}}}

八、选择建议

场景推荐通知
需要控制方法是否执行(如权限校验)@Around
需要修改返回值@Around
只需要在方法前做处理(如日志)@Before
只需要处理方法返回值@AfterReturning
只需要处理异常情况@AfterThrowing
需要释放资源(无论成功失败)@After
性能监控(计算耗时)@Around

九、注意事项

  1. @Around最强大,可以替代其他所有通知,但不要滥用
  2. @Before无法阻止方法执行,只能在前做处理
  3. @AfterReturning只在成功时执行,异常时不执行
  4. @AfterThrowing只在异常时执行,成功时不执行
  5. @After无论如何都会执行,类似finally
  6. 多个切面的执行顺序可以使用@Order注解控制
  7. 切入点表达式越精确越好,避免不必要的拦截

总结:

  • execution是最强大的切入点表达式,几乎可以匹配任何方法
  • @Around是最灵活的通知类型,可以完全控制方法的执行
  • 实际开发中,@Around+execution/@annotation组合使用最为常见
http://www.cnnetsun.cn/news/1833376.html

相关文章:

  • 钢结构厂房通风排烟天窗选型与安装要点(附国标图集要求)
  • 2025届毕业生推荐的六大AI写作网站横评
  • S32K3XX时钟树实战:从EB配置到外设时钟精准分配
  • MoneyPrinterPlus:AI视频创作革命,让普通人也能成为短视频创作大师
  • 如何用kill-doc脚本轻松下载各大文库文档:三步告别广告和登录验证
  • 限流规则写死=技术负债!用OpenTelemetry+Grafana Loki构建可观测熔断决策闭环(附2024最新eBPF内核级流量采样方案)
  • 从“已爆发”到“将爆发”——Infoseek舆情系统重构预警的时间线
  • AI原生研发决策树不是流程图,而是生存指南:20年踩过137次技术栈陷阱后凝练的6个不可逆判定节点(含SLO反向约束校验机制)
  • ROS2与ROS1多机通信对比:用Domain ID替代Master URI的新玩法
  • DWT基础应用与获取程序运行时间Debug练习(上)
  • WinCC7.5+Telegraf+Influxdb 3.0 Core:通过OPC UA方式WinCC数据直接同步数据到Influxdb
  • Ubuntu 22.04 + PyTorch 2.3 环境:PyG 2.5+ 一键安装与版本兼容性实战
  • 从手机充电器到电动车BMS:图解多电源系统中电流回路的3个关键设计原则
  • 我用 AI 辅助开发了一系列小工具():文件提取工具邮
  • 如何轻松玩转怀旧Flash游戏?这个免费工具帮你搞定一切!
  • Mysql的行级锁到底是怎么加的?谌
  • CSS变量与自定义属性
  • 我们为什么放弃了ActiveMQ,转向了Pulsar?
  • RAG详解:让大模型看见你的私有知识
  • 整合素家族核心靶点解析:CD51(Integrin αv)的分子机制与药物研发技术前瞻
  • Pandas显示设置全攻略:如何让数据表格在Jupyter Notebook中更美观(附常见问题解决)
  • 事件驱动化技术中的事件发布事件订阅与事件处理
  • 计算机毕业设计:Python空气质量智能评估与预测平台 Django框架 Spark 线性回归 可视化 大数据 机器学习 深度学习(建议收藏)✅
  • Upscayl图像放大GPU加速深度优化:告别Vulkan兼容性困扰
  • Gemma-3-270m应用场景:政务公文润色、政策文件要点速读生成案例
  • 酷安UWP桌面客户端:Windows平台上的酷安社区完整体验指南
  • 日本Shopify消费趋势分析:樱花季与新生活季正在带火哪些品类?
  • 打字不如说话,说话不如截图——AI 代码助手的多模态输入实践兑
  • 2026届必备的五大降重复率平台解析与推荐
  • LeetCode 删除无效的括号:python 题解檀