Spring AOP 中记录日志
Spring AOP 中记录日志
使用 AOP 和 Spring 提供的 RequestContextHolder 在通知中记录 HTTP 请求相关日志。以下是进阶添加日志功能的完整例子和说明。
完整示例
1. 切面类实现
@Aspect
@Component
public class LogAspect {@Around("@annotation(log)") // 拦截所有标注 @Log 的方法public Object logExecution(ProceedingJoinPoint joinPoint, Log log) throws Throwable {// 获取 HttpServletRequest 对象ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();// 提取请求信息String url = request.getRequestURL().toString();String method = request.getMethod();String ip = request.getRemoteAddr();String params = request.getQueryString();// 方法名和参数String methodName = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();// 记录日志 - 方法执行前System.out.println("请求 URL: " + url);System.out.println("HTTP 方法: " + method);System.out.println("请求 IP: " + ip);System.out.println("请求参数: " + params);System.out.println("方法名称: " + methodName);System.out.println("方法参数: " + Arrays.toString(args));long startTime = System.currentTimeMillis();// 执行目标方法Object result;try {result = joinPoint.proceed(); // 执行被拦截的方法} catch (Throwable ex) {// 异常处理System.err.println("方法执行异常: " + methodName + ", 异常信息: " + ex.getMessage());throw ex;}long timeTaken = System.currentTimeMillis() - startTime;// 记录日志 - 方法执行后System.out.println("方法执行完成: " + methodName + ", 返回值: " + result + ", 耗时: " + timeTaken + "ms");return result; // 返回目标方法的执行结果}
}
2. 自定义注解
在需要记录日志的方法上标注自定义注解 @Log:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {String value() default "";
}
3. 控制器示例
在控制器方法上使用 @Log 注解:
@RestController
@RequestMapping("/api")
public class TestController {@GetMapping("/test")@Log("测试日志记录")public String testLog(@RequestParam String input) {if ("error".equals(input)) {throw new RuntimeException("模拟异常");}return "Hello, " + input;}
}
日志输出示例
正常请求
访问 http://localhost:8080/api/test?input=world ,记录如下:
请求 URL: http://localhost:8080/api/test
HTTP 方法: GET
请求 IP: 127.0.0.1
请求参数: input=world
方法名称: testLog
方法参数: [world]
方法执行完成: testLog, 返回值: Hello, world, 耗时: 10ms
异常请求
访问 http://localhost:8080/api/test?input=error ,记录如下:
请求 URL: http://localhost:8080/api/test
HTTP 方法: GET
请求 IP: 127.0.0.1
请求参数: input=error
方法名称: testLog
方法参数: [error]
方法执行异常: testLog, 异常信息: 模拟异常
关键点解析
1. 为什么使用 RequestContextHolder?
HttpServletRequest是与线程绑定的,通过RequestContextHolder可以方便地在 AOP 切面中获取当前请求的HttpServletRequest对象。
2. 日志内容可记录什么?
- 请求的 URL (
request.getRequestURL()); - HTTP 方法 (
request.getMethod()); - 客户端 IP 地址 (
request.getRemoteAddr()); - 请求参数 (
request.getQueryString()); - 被拦截方法的名称和参数 (
joinPoint.getSignature()和joinPoint.getArgs()); - 方法执行耗时。
3. 异常处理
- 在
catch块中记录方法执行时报出的异常信息,以便后续排查问题。
总结
- 通过 AOP 和
RequestContextHolder,在通知中进行统一的日志记录,便于跟踪和排查 HTTP 请求相关的信息。 @Around通知允许在方法执行前后和异常情况下插入日志逻辑,适用于统一的日志记录场景。
相关文章:
Spring AOP 中记录日志
Spring AOP 中记录日志 使用 AOP 和 Spring 提供的 RequestContextHolder 在通知中记录 HTTP 请求相关日志。以下是进阶添加日志功能的完整例子和说明。 完整示例 1. 切面类实现 Aspect Component public class LogAspect {Around("annotation(log)") // 拦截所有…...
udp tcp协议
文章目录 1. UDP协议1.1 端口号1.2 UDP协议格式1.3 UDP特性1.4 报文的封装 2. TCP协议2.1 TCP协议格式2.2 TCP策略2.2.1 确认应答机制(ACK)序号与确认序号6个标志位序号的理解 2.2.2 超时重传机制2.2.3 连接管理机制三次握手四次挥手理解三次握手理解四次挥手 2.2.4 流量控制2.…...
C语言结构体详细讲解
文章目录 [TOC] 一、前言二、结构体2.1 结构体概念🎈2.2 结构体定义🎉2.3 结构体使用🎗️ 结尾 时间紧后面还有一些知识点这周内补上, 理解理解!(❁◡❁) 一、前言 在学习结构体之前,讲讲为什么会专门写一章博客来分享…...
公交车信息管理系统:实现交通数据的智能化处理
概述 在对系统进行设计之前,需要对选题进行需求分析、可行性分析、流程分析、数据字典等内容。根据需求分析阶段,大致确定用户使用系统所需要具有的功能模块需求,由此规划出系统需要设计的相关功能模块。根据可行性分析阶段,确定系…...
在 Windows 下生成 .tgz 文件的方法
方法 1:使用 7-Zip 7-Zip 是一个流行的免费压缩工具,支持生成 .tar.gz 格式。 步骤: 下载并安装 7-Zip。准备好要压缩的文件或文件夹。右键点击文件或文件夹,选择 7-Zip > 添加到压缩文件...。在弹出的对话框中:…...
编程式浪漫,100款圣诞树代码分享
最近这几天有很多小伙伴开始寻找各种各样的圣诞树代码,我们最常用的Java,Python,C语言,前端,都是可以实现的。小巫师,就在这里分享超火的圣诞树代码,源码分享! 01.HTML圣诞树源代码…...
Nacos的下载和启动(如何快速稳定下载在github中)
目录 Nacos的下载 下载加速器 在githup中找到Nacos 启动Nacos 访问Nacos Nacos的下载 下载加速器 首先,我们需要进入githup中,我们直接访问,肯定是访问不到的。 这里我们经常玩游戏的同学肯定知道steam,这个加速器。直接进入…...
python基础知识(六)
文章目录 连接Mysql数据库安装Mysql数据库连接数据库创建数据库创建数据表查询表是否存在设置主键插入数据批量插入查询、删除、更新数据 使用PyMySql连接数据库安装PyMySql连接数据库 连接MongoDB安装pymongo驱动在MongoDB创建库及数据插入文档查询数据修改数据文档排序删除数…...
神经网络-LeNet
LeNet在1990年被提出,是一系列网络的统称,包括了LeNet1~LeNet5,对于神经网络的学习者来说,大家对下面这个图一定很熟悉,该图是对LeNet的简化展示。 在LeNet中已经提出了卷积层、Pooling层等概念,只是但是由…...
es 中 terms set 使用
在 Elasticsearch 中,terms_set 查询通常用于在一个字段上进行多值匹配,并支持设置一个条件(例如最小匹配数量),让查询结果更具灵活性。为了展示如何使用 terms_set 查询,我们首先会创建一个索引࿰…...
绩效考核试题
1.2.绩效考核 ()通过财务、客户、内部运营、学习与成长4个角度,将组织战略目标逐层分解转化为细化指标,有差异地针对不同的指标进行不同时期的绩效评估,有助于组织战略目标的实现。 A目标管理法 B平衡计分卡法 C硬性分…...
停车管理系统:构建安全、便捷的停车环境
Tomcat 简介 只要学习Java Web项目就不得不学习Tomcat。Tomcat是一种免费的开源的一种Java Web项目的容器,完美继承了 Apache服务器的特性,并且里面添加可以自动化运行的Java Web组件,让Java Web项目可以完全的运行到Tomcat里面。对于特大型项…...
十四、从0开始卷出一个新项目之瑞萨RZN2L之栈回溯(Default_Handler/hartfault)
目录 一、概述 二、参考资料 三、代码 四、日志 五、定位函数调用 六、README和工具 一、概述 软件开发中常见的比较棘手的问题就是hartfault/Default_Handler/dump,俗称跑飞了。 参考cmbacktrace,在瑞萨RZN2L/T2M实现栈回溯,串口打印…...
联通光猫怎么自己改桥接模式?
环境: 联通光猫 ZXHN F677V9 硬件版本号 V9.0 软件版本号 V9.0.0P1T3 问题描述: 联通光猫怎么自己改桥接模式 家里用的是ZXHN F677V9 光猫,最近又搞了个软路由,想改桥接模式 解决方案: 1.拿到最新超级密码&…...
突围边缘:OpenAI开源实时嵌入式API,AI触角延伸至微观世界
当OpenAI宣布开源其名为openai-realtime-embedded-sdk的实时嵌入式API时,整个科技界都为之震惊。这一举动意味着,曾经遥不可及的强大AI能力,如今可以被嵌入到像ESP32这样的微型控制器中,真正地将AI的触角延伸到了物联网和边缘计算…...
springBoot Maven 剔除无用的jar引用
目录 Used undeclared dependencies found Unused declared dependencies found 当项目经过一段时间的开发和维护后,经常会遇到项目打包速度变慢的问题。这通常与项目中包含大量的jar依赖有关,这些依赖之间的关系错综复杂。这种情况在项目维护过程中是…...
malloc 分配大堆块(128KB)的一次探索
前言 一次意外执行了 malloc(0x5000),结构使用 gdb 调试发现其分配的位置在 TLS 区域,这令我不解(:最后去看了下 malloc 源码和 mmap 源码实现,发现似乎可能是 gdb 插件的问题,乐 场景复现 #include <…...
Android -- 双屏异显之方法二
Android – 双屏异显之方法二: DisplayManager PS: 1. 使用改方法主板需连接至少两个输出显示屏; 2. 副屏内部实现与MediaRouter下一样;使用方法 # 主屏activity内: private SecondDisplay secondDisplay;private void dualScreen3288() {D…...
电脑使用CDR时弹出错误“计算机丢失mfc140u.dll”是什么原因?“计算机丢失mfc140u.dll”要怎么解决?
电脑使用CDR时弹出“计算机丢失mfc140u.dll”错误:原因与解决方案 在日常电脑使用中,我们时常会遇到各种系统报错和文件丢失问题。特别是当我们使用某些特定软件,如CorelDRAW(简称CDR)时,可能会遇到“计算…...
使用RDMA技术构建无损网络
如何使用RDMA构建无损网络? 在深入研究RDMA和无损网络领域后,会经常遇到两个基本问题:为什么采用无损网络至关重要?这些先进技术有什么优势? 无损网络是一种新型的网络技术,它可以在不丢失数据包的情况下传…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈
【导读】 本文针对无人机(UAV)视频中目标尺寸小、运动快导致的多目标跟踪难题,提出一种更简单高效的方法。核心创新在于从低置信度检测启动跟踪(贴合无人机场景特性),并改进传统外观匹配算法以关联此类检测…...
【JavaEE】万字详解HTTP协议
HTTP是什么?-----互联网的“快递小哥” 想象我们正在网上购物:打开淘宝APP,搜索“蓝牙耳机”,点击商品图片,然后下单付款。这一系列操作背后,其实有一个看不见的“快递小哥”在帮我们传递信息,…...
