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和无损网络领域后,会经常遇到两个基本问题:为什么采用无损网络至关重要?这些先进技术有什么优势? 无损网络是一种新型的网络技术,它可以在不丢失数据包的情况下传…...
数据结构与算法的实战场景剖析(持续更新)
1. 排序算法在数据库索引中的实战应用 数据库索引就像图书馆的目录系统,而排序算法就是构建这个目录的核心工具。在实际项目中,我们经常需要根据不同的查询需求选择合适的排序算法来构建索引。比如MySQL的InnoDB引擎就采用了B树作为索引结构,…...
银保监现场检查倒计时:如何 1 天内生成全量口径文档?
面对银保监现场检查对数据口径“可追溯、可验证”的严苛要求,传统人工或表级血缘工具效率低下且准确性不足。本文介绍基于 算子级血缘 与 主动元数据 的自动化解决方案,通过将复杂 SQL 加工逻辑“白盒化”,实现监管指标口径的 一键溯源 与 自…...
BFS入门经典
#include <cstring> #include <iostream> #include <algorithm> #include <queue>using namespace std;// pair<int,int> 用来存一个点的坐标 (x, y) typedef pair<int, int> PII;const int N 110;int n, m; // n 行 m 列 i…...
我不是狐狸,我是那Harness Engineering律
Julia(julialang.org)由Stefan Karpinski、Jeff Bezanson等在2009年创建,目标是融合Python的易用性、C的高性能、R的统计能力、Matlab的科学计算生态。 其核心设计哲学是: 高性能:编译型语言(JIT࿰…...
Horizon UAG配置踩坑实录:为什么你的连接服务器状态总是红色?
Horizon UAG配置实战:从红色警报到绿色畅通的完整指南 当你盯着Horizon UAG管理界面那个刺眼的红色连接状态时,那种挫败感我深有体会。作为企业虚拟桌面架构的关键组件,UAG网关服务器的配置问题可能导致整个远程办公系统瘫痪。本文将带你深入…...
Phi-3-mini-4k-instruct-gguf入门指南:中文标点智能补全、引号嵌套处理与段落空行控制
Phi-3-mini-4k-instruct-gguf入门指南:中文标点智能补全、引号嵌套处理与段落空行控制 1. 认识Phi-3-mini-4k-instruct-gguf Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本,特别适合中文场景下的问答、文本改写、摘要整理…...
深入探索Linux Test Project:专业级Linux系统测试框架完全指南
深入探索Linux Test Project:专业级Linux系统测试框架完全指南 【免费下载链接】ltp Linux Test Project (mailing list: https://lists.linux.it/listinfo/ltp) 项目地址: https://gitcode.com/gh_mirrors/ltp/ltp Linux Test Project(LTP&#…...
HagiCode Desktop 混合分发架构解析:如何用 PP 加速大文件下载抖
一、Actor 模型:不是并发技巧,而是领域单元 Actor 模型的本质是: Actor 是独立运行的实体 Actor 之间只通过消息交互 Actor 内部状态不可被外部直接访问 Actor 自行决定如何处理收到的消息 Actor 模型真正解决的是: 如何在不共享状…...
2026奇点大会AI部署白皮书深度解密(Kubernetes+LLM Runtime双栈融合架构首次公开)
第一章:2026奇点智能技术大会:AI原生容器化部署 2026奇点智能技术大会(https://ml-summit.org) AI原生容器化部署已成为大模型服务落地的核心范式。与传统微服务容器化不同,AI原生部署需同时满足GPU资源弹性调度、模型权重分片加载、推理请求…...
IM系统核心不是聊天?深入剖析SpringBoot+Netty项目中关系链与群组模块的设计陷阱
IM系统核心不是聊天?深入剖析SpringBootNetty项目中关系链与群组模块的设计陷阱 当大多数人谈论即时通讯系统时,首先想到的是消息收发功能。然而,真正让微信、QQ等产品形成护城河的,并非简单的消息传输能力,而是其背后…...
