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

Spring AOP

一·

AOP(面向切面编程)思想,简单理解为:把多个方法的重复逻辑(比如统计耗时、打印日志)抽离成“统一
逻辑”,一次性作用到目标方法上,不用逐个修改方法。
比如想知道业务层的所有方法耗时情况:

  • 连接点(JoinPoint):程序执行过程中可被AOP拦截的所有点(Spring AOP中仅指方法执行),即
    “所有能被 AOP 控制的方法”;
  • 切入点(Pointcut):连接点中“实际被选中的方法”(比如所有Service层方法),由@Pointcut+切
    点表达式定义;
  • 通知(Advice):需要对切入点方法执行的重复逻辑(比如统计耗时),体现为一个方法,
    @Around/@AfterThrowing 等注解指明“通知执行的时机”(环绕/异常后);
  • 切面(Aspect):描述“通知”和“切入点”的对应关系(比如“统计耗时的通知”作用于“所有
    Service 层方法”),用@Aspect标记切面类(需配合@Component 交给容器管理);
  • 目标对象(Target):切入点所指向的类的对象

AOP是通过动态代理技术实现的。首先为目标对象生成一个代理对象,如果目标对象实现了接口,则和目标对
象实现同一个接口,如果没有,则继承目标对象。然后再实现里面的方法,方法里面就是把通知里的逻辑和调
用的目标对象的切入点方法整合到一起。然后把代理对象交给Spring的IOC容器去处理。如果Controller中需要
注入时,注入的就是代理对象了

二·AOP 五大通知类型

  • 前置通知 @Before 切入点方法执行前 前置校验(如参数检查)、日志记录
  • 后置通知 @After 切入点方法执行后(无论是否异常) 资源释放、最终兜底操作
  • 返回通知 @AfterReturning 切入点方法正常返回后 处理返回结果(如数据加工)
  • 异常通知 @AfterThrowing 切入点方法抛出异常后 统一异常捕获、报错日志记录
  • 环绕通知 @Around 切入点方法执行前后(全程包裹) 耗时统计、权限控制(最灵活)
    补充
  • 环绕通知(@Around)需手动调用 joinPoint.proceed() 执行原方法,是唯一能控制原方法是否执行的通知;
  • 环绕通知方法的返回值必须指定为Object来接收原始方法的返回值
    日常开发中,@Around(耗时 / 日志)+ @AfterThrowing(异常)是最常用的组合

三·通知顺序

当有多个切面的切入点都匹配到了目标方法时,多个通知方法都会运行。运行顺序如下:

默认按照类名字母排序

目标方法前的通知方法:字母靠前的先执行
目标方法后的通知方法:字母考前的后执行

如果切面类用@Order()来控制了

数字小的先执行

四·切入点表达式

  1. 基于方法签名的 execution 表达式(最常用)
    核心格式:execution(返回值类型 包名.类名.方法名(参数类型))简化规则:
  • 表示 “任意”(任意返回值 / 类 / 方法);
    .. 表示 “任意参数 / 任意子包”;
    2.基于自定义注解标志的方法来找到切入点方法
    ① 自定义注解(如 @Log);
    ② 给目标方法加 @Log;
    ③ 切点表达式写 @annotation(com.xxx.annotation.Log);里面是自定义注解的全类名

五·连接点

spring中用JoinPoint抽象了连接点,可以用它获得方法执行时的相关信息,如目标类名,方法名,方法参数等。

目标对象 joinPoint.getTarget() 所有 JoinPoint com.xxx.service.UserServiceImpl@123456
目标对象类名 joinPoint.getTarget().getClass().getName() 所有 JoinPoint com.xxx.service.UserServiceImpl
执行的方法名 joinPoint.getSignature().getName() 所有 JoinPoint findUserById
方法全限定名 joinPoint.getSignature().toLongString() 所有 JoinPoint public com.xxx.entity.User com.xxx.service.UserServiceImpl.findUserById(Long)
方法参数数组 joinPoint.getArgs() 所有 JoinPoint [1001](参数为 Long 类型的 1001)
代理对象 joinPoint.getThis() 所有 JoinPoint

注意:

  • 对于@Around通知,获取连接点信息只能用 ProceedingJoinPoint
  • 对于其他四种,只能用 JoinPoint 他是ProceedingJoinPoint的父类
http://www.jsqmd.com/news/100831/

相关文章:

  • 实战为王!数眼智能 AI 网页解析全流程操作(含 API 接入 + 竞品分析)
  • 带你搞懂BootLoader(四)-第三个BootLoader
  • 【案例共创】从0开始使用华为云开发者空间搭建房价预测模型
  • vLLM推理引擎教程6-Nsight Systems性能分析
  • JX6-CON1控制器模块
  • 海外回国eSIM避坑指南一定要提前搞懂,不然真的会被坑惨!
  • spark读hive偶尔出现table not found
  • keyence颜色传感器LR-W70使用(最多可区分16种颜色)
  • Wan2.2-T2V-A14B模型部署与高保真T2V实战
  • Kubernetes Debug 专用镜像实践指南
  • AIGC简介
  • LangGraph4j 入门
  • 基于VUE的企业信息管理系统 [VUE]-计算机毕业设计源码+LW文档
  • Linux SSH隧道代理转发及多层转发
  • 硬核拆解:这套电影解说工作流,如何帮你零成本搭建AI影视解说SaaS
  • 12/16
  • LobeChat安全与权限管理实战解析
  • Nano Banana Pro 如何重塑 AI 驱动的教育未来
  • 黑科技加持,工作效率翻倍!这 9 款小众软件宝藏盘点
  • 女朋友到家前 10 分钟,空调自动开暖风(小智 MCP 实战)
  • 12.12 标签(四) 表格
  • 海报设计无从下手?这3个技巧让你告别空白画布
  • LobeChat能否实现段落缩写功能?长文本精炼助手
  • β-Amyloid (25-35);GSNKGAIIGLM
  • Hutool Beanutil.copyproperties() 是浅拷贝还是深拷贝 - Higurashi
  • 【小白笔记】大数加法
  • 课题申报新手入门必备指南!利用AI辅助搞定 6大关键部分,高效提升申报成功率(附AI提示词)
  • Java面试题含答案——2025年最新完整分享,收藏这篇就够了
  • Flutter状态管理全解析:Provider vs Bloc vs Riverpod实战对比
  • unity中简单控制角色移动及动画实例--以及角色动画抖动残影拖影处理