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

ProceedingJoinPoint的认识

ProceedingJoinPoint 是 Spring AOP(面向切面编程) 中的核心接口,用于在 环绕通知(@Around) 中拦截方法调用并控制其执行流程。以下是对其功能和用法的详细解释:

核心作用

拦截目标方法

  • 在方法执行前后插入自定义逻辑,例如日志记录、性能监控、事务管理等。

获取方法元数据

  • 通过 ProceedingJoinPoint 可以获取被拦截方法的名称、参数、注解等信息。

控制方法执行

  • 决定目标方法是否执行、何时执行,甚至修改方法参数或返回值。

关键方法

方法描述
proceed()执行目标方法,返回方法的返回值。若不调用该方法,目标方法将不会执行。
proceed(Object[] args)带参数执行目标方法,可修改参数值后再执行。
getSignature()获取方法签名,用于获取方法名、参数类型等信息。
getArgs()获取方法的参数数组。
getTarget()获取目标对象(即被代理的对象)。

典型应用场景

  1. 性能监控
@Around("execution(* com.example.service.*.*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();// 执行目标方法Object result = joinPoint.proceed();long endTime = System.currentTimeMillis();System.out.printf("方法 %s 执行耗时: %dms%n", joinPoint.getSignature().getName(), (endTime - startTime));return result;
}
  1. 参数校验
@Around("@annotation(com.example.ValidateParam)")
public Object validateParams(ProceedingJoinPoint joinPoint) throws Throwable {Object[] args = joinPoint.getArgs();for (Object arg : args) {if (arg == null) {throw new IllegalArgumentException("参数不能为空");}}return joinPoint.proceed();  // 参数合法,继续执行目标方法
}
  1. 异常处理
@Around("execution(* com.example.dao.*.*(..))")
public Object handleDatabaseException(ProceedingJoinPoint joinPoint) {try {return joinPoint.proceed();} catch (SQLException e) {log.error("数据库操作失败: {}", e.getMessage());throw new RuntimeException("数据库操作异常", e);}
}

与其他 JoinPoint 的区别:
(类型 适用场景 核心功能)
ProceedingJoinPoint:@Around 注解 可控制目标方法的执行(必须调用 proceed()),获取方法参数和返回值。
JoinPoint :@Before、@After 等注解只能获取方法信息(如参数、签名),无法控制方法的执行(不能调用 proceed())。

注意事项

  1. proceed() 必须调用
    在 @Around 通知中,若不调用 proceed(),目标方法将不会执行。

  2. 异常处理
    proceed() 可能抛出异常,需在环绕通知中进行处理。

  3. 参数修改
    通过 proceed(Object[] args) 可修改参数值,但需注意参数类型匹配。

总结
ProceedingJoinPoint 是实现 环绕通知 的关键接口,通过它可以:

  • 在方法执行前后插入自定义逻辑。
  • 动态修改方法参数或返回值。
  • 处理异常和控制方法执行流程。

这种机制使得 AOP 能够在不修改原有业务代码的前提下,增强系统功能(如日志、事务、权限等),体现了 “约定优于配置” 的设计理念。

http://www.xdnf.cn/news/6458.html

相关文章:

  • 机器学习分类
  • AM1.5G太阳光模拟器参数
  • DeepSeek推理优化技巧:提升速度与降低成本
  • 代码随想录算法训练营第四十一天
  • 【Pandas】pandas DataFrame eval
  • STM32 DMA技术深度解析:从原理到实战应用讲解
  • 激光雷达视觉定位是3D视觉定位吗?
  • GCC 使用说明
  • 专项智能练习(定义判断)_DA_01
  • 案例:塔能精准能耗节能技术,驱动工厂智能变革
  • 异步日志系统01——日志系统框架
  • 扬州卓韵酒店用品:优质洗浴用品,提升酒店满意度与品牌形象
  • 应用BERT-GCN跨模态情绪分析:贸易缓和与金价波动的AI归因
  • OpenCV CUDA模块中矩阵操作------范数(Norm)相关函数
  • 面试题:介绍一下JAVA中的反射机制
  • Springboot考研信息平台
  • 25.第二阶段x64游戏实战-分析物品相关数据
  • CSS 布局系统深度解析:从传统到现代的布局方案
  • 深入浅出:Windows系统DLL劫持提权原理
  • Java Socket编程完全指南:从基础到实战应用
  • SSTI 刷刷刷个题
  • 使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据(申请key教程)
  • 电总协议调试助手更新-PowerBus-v1.0.5
  • 实验5 DNS协议分析与测量
  • 油漆面积--二维差分求区间变化
  • 测序的原理
  • java-JUC概述(进行分类总结-包含原子类、并发集合、线程等)
  • 生成式AI在编程中的应用场景:从代码生成到安全检测
  • 【数据结构】链表 LinkedList
  • Rust 学习笔记:关于 Vector 的练习题