【注解+aop 记录日志】关于如何使用自定义 @Log 注解实现 Spring AOP 操作日志记录功能的详细教程

Java基于注解实现日志记录模块,超详细注释! 在项目开发过程中,日志记录是一个至关重要的环节,它能够帮助开发人员追踪用户的重要操作,如新增、删除、修改等,从而有效监控系统的运行状态。通过日志记录,我们可以深入了解系统的运行情况,及时发现并解决问题,优化性能,提高用户体验。 阅读详情

🚀 Spring AOP + 自定义注解实现操作日志记录功能教程


🟢 一、功能简介与优势

✅ 简单用法(示例)

@DeleteMapping("/{NewsIds}")
@Log(title = "【新闻信息】", businessType = BusinessType.DELETE)
public AjaxResult remove(@PathVariable Long[] NewsIds) {
    return toAjax(appNewsService.deleteAppNewsByNewsIds(NewsIds));
}

只需在方法上添加 @Log 注解,系统就会自动记录调用的参数、返回值、模块名、操作类型等日志信息,无需手动写日志。


🎯 优势亮点

优势说明
✅ 解耦日志逻辑日志记录逻辑通过 AOP 与业务代码解耦,统一管理
✅ 简单统一一句注解搞定所有日志,开发成本低
✅ 自动化自动记录请求参数、返回值、异常等
✅ 高度可扩展可按需拓展日志记录方式(保存数据库、ES、链路追踪等)
✅ 支持排除参数可配置排除敏感字段,如密码、Token 等

二、实现步骤与代码讲解


1️⃣ 定义日志注解 @Log

@Target({ ElementType.PARAMETER, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log { /** 模块标题 */ String title() default ""; /** 功能类型(参考 BusinessType 枚举) */ BusinessType businessType() default BusinessType.OTHER; /** 操作人类别(默认后台管理用户) */ OperatorType operatorType() default OperatorType.MANAGE; /** 是否保存请求参数 */ boolean isSaveRequestData() default true; /** 是否保存响应结果 */ boolean isSaveResponseData() default true; /** 排除指定的参数名(如 password) */ String[] excludeParamNames() default {}; } 

2️⃣ 定义业务类型枚举 BusinessType

public enum BusinessType {
    OTHER,      // 其它
    INSERT,     // 新增
    UPDATE,     // 修改
    DELETE,     // 删除
    SELECT,     // 查询
    EXPORT,     // 导出
    IMPORT,     // 导入
    LOGIN,      // 登录
    LOGOUT      // 登出
}
 

可根据实际项目拓展 BusinessType 的枚举项。


3️⃣ 编写切面类 LogAspect

@Aspect @Component public class LogAspect { private static final Logger logger = LoggerFactory.getLogger(LogAspect.class); /** 切入点:拦截所有 @Log 注解的方法 */ @Pointcut("@annotation(com.elinesign.common.annotation.Log)") public void logPointCut() {} /** 正常返回通知:记录操作日志 */ @AfterReturning(pointcut = "logPointCut()", returning = "result") public void doAfterReturning(JoinPoint joinPoint, Object result) { handleLog(joinPoint, null, result); } /** 异常通知:记录异常日志 */ @AfterThrowing(pointcut = "logPointCut()", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Exception e) { handleLog(joinPoint, e, null); } /** 核心日志处理逻辑 */ protected void handleLog(final JoinPoint joinPoint, final Exception e, Object result) { try { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Log log = method.getAnnotation(Log.class); if (log == null) return; // 提取日志信息 String title = log.title(); String businessType = log.businessType().name(); String className = joinPoint.getTarget().getClass().getName(); String methodName = signature.getName(); Object[] args = joinPoint.getArgs(); String params = java.util.Arrays.deepToString(args); String resultStr = result != null ? result.toString() : "null"; // 打印日志 if (e != null) { logger.error("[操作日志-异常] 标题: {} | 类型: {} | 类: {} | 方法: {} | 参数: {}", title, businessType, className, methodName, params, e); } else { logger.info("[操作日志] 标题: {} | 类型: {} | 类: {} | 方法: {} | 参数: {} | 返回: {}", title, businessType, className, methodName, params, resultStr); } } catch (Exception ex) { logger.error("日志切面处理异常", ex); } } } 

4️⃣ 实际使用示例

@PostMapping("/add") @Log(title = "新增用户", businessType = BusinessType.INSERT) public AjaxResult addUser(@RequestBody User user) { return userService.addUser(user); } 

执行该接口后,日志会自动记录类似:

[操作日志] 标题: 新增用户 | 类型: INSERT | 类: com.example.controller.UserController | 方法: addUser | 参数: [User{id=1, name=张三}] | 返回: AjaxResult{code=200, msg='成功'}


📌 三、可选增强(推荐)

  • ✔️ 将日志写入数据库,可定义 SysLog 实体 + LogService 服务类

  • ✔️ 日志异步处理(防止主线程卡顿)

  • ✔️ 过滤敏感字段(如 password、token)

  • ✔️ 记录请求 IP、当前登录用户、请求 URL 等信息


✅ 四、总结

特性说明
注解驱动一行注解,统一记录日志
非侵入式不影响原有业务逻辑
易于维护统一处理、集中管理
易于拓展可落库、异步处理、链路追踪

🔧 五、实现原理概述

该日志记录功能的实现依赖于:

  • ✅ 自定义注解 @Log:用于标识哪些方法需要记录操作日志;

  • ✅ Spring AOP(面向切面编程):用于在方法执行 前/后/异常时 拦截标注了 @Log 注解的方法;

  • ✅ 通过 AOP 拿到方法上下文(类名、方法名、参数、返回值、异常等);

  • ✅ 利用日志框架(如 SLF4J + Logback)进行输出。


🧠 六、关键技术原理详解

🔹 1. Spring AOP 的工作原理

Spring AOP(Aspect-Oriented Programming)允许我们在不修改业务代码的前提下,向特定方法添加额外逻辑,比如日志、事务、权限控制等。

在这套日志功能中:

  • @Aspect 定义了一个切面类 LogAspect

  • @Pointcut 指定了切入点:所有带 @Log 注解的方法

  • @AfterReturning 表示:方法正常返回后执行日志记录

  • @AfterThrowing 表示:方法抛出异常时也记录日志

💡 核心机制依赖于 Spring 的代理模式(JDK 动态代理或 CGLIB 代理),将目标类封装在代理对象中,执行时插入横切逻辑。


🔹 2. 注解驱动设计原理

你定义了一个注解 @Log,它本身不会产生任何效果,但通过 AOP:

Log log = method.getAnnotation(Log.class);

这个逻辑会在运行时通过反射读取方法上的注解内容(如标题、操作类型等),然后根据注解配置打印日志。

这是一种声明式编程模式,开发者只需要声明注解,不必处理日志逻辑。


🔹 3. JoinPoint 作用

public void handleLog(JoinPoint joinPoint, Exception e, Object result)

JoinPoint 提供了方法执行的上下文信息,包括:

信息示例
类名com.example.controller.AppNewsController
方法名remove
参数列表[1,2,3]
返回结果AjaxResult
异常信息NullPointerException

这使得你可以记录谁在什么时候操作了什么内容。


🔹 4. 注解 + AOP 的好处

  • 解耦日志逻辑与业务代码

  • 统一记录风格,方便后期接入数据库、审计平台

  • 可插拔性强:不想记录某方法日志,只需移除注解


🖇️ 七、执行流程图(简化)

Controller 方法被调用
     ↓
Spring AOP 检查该方法是否有 @Log 注解
     ↓ 是
LogAspect 拦截该方法:
     - 方法执行成功 → 执行 doAfterReturning()
     - 方法抛出异常 → 执行 doAfterThrowing()
     ↓
handleLog() 获取方法上下文 + 注解内容
     ↓
打印日志(或写入数据库)


🧭 八、常见问题解答

❓ Q1: 为什么使用注解而不是统一拦截所有方法?

答:使用注解可以更精准地控制哪些方法需要记录日志,避免无效日志信息干扰。


❓ Q2: 为什么不在 Controller 里直接写 logger.info()?

答:AOP 的优势在于统一处理、解耦逻辑、不影响原有业务代码,增强系统可维护性与可读性。


❓ Q3: 方法参数是对象怎么办?会打印太多吗?

答:可以

  • 用 excludeParamNames 排除敏感字段

  • 或扩展参数打印逻辑,对对象参数进行序列化再打印(如转 JSON)

一个注解搞定,记录项目日志 最近正在录制 TienChin 项目视频~采用 Spring Boot+Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和我一起做一个完成率超 90% 的项目。 前段时间做了一个支线任务,现在还是回到我们的主线上面来,继续完成 TienChin 项目。 小伙伴们知道我最近在录制 TienChin 项目视频教程,这是一个基于 RuoYi-Vue 脚手架的项目,用过这个脚手架的小伙伴可能知道,这个脚手架有一个功能,就是如果你需要记录下来一个接口的操作信息,那么只需要在 Controller 接口中加 阅读详情

相关推荐

基于AOP和ThreadLocal实现日志记录

基于AOP和ThreadLocal实现日志记录 主要功能实现 : 在API每次被请求时,可以在整个方法调用链路中记录一条唯一的API请求日志,可以记录请求中绝大部分关键内容。并且可以自定义实现对日志收集(直接标准输出,或写入到文件或数据库)。 比如传参,响应,请求url,请求方法,clientIp,耗时,请求成功或异常,请求头等等。 实现的核心为AOP以及ThreadLocal。 AOP 会切所有被@Log4a注解的方法,会记录一个线程中唯一一个Log4对象,读取AOP中的方法信息(入参,方法等等) 抓

EalenXie的博客 826

Spring实现日志注解

1、目的 写项目的时候经常会通过日志来排查原因,一种是通过log4j将日志收集出来,然后使用elk进行数据的分类与统计,这种是针对大量的请求日志进行记录。另一种就是通过自定义注解的方式写入数据库,这种是针对特定接口来处理,将重要的操作信息记录到数据库中。这篇博客就是说的第二种方式。 2、思路 首先,应该使用自定义注解来标记哪些接口需要记录操作日志。 然后, 使用切面来统一拦截参数和返回的结果,并将信息返回到数据库。 3、实现过程 4、实现效果 5、总结 ...

qq_38345598的博客 2666

spring简单注解+log4j记录日志

简单的demo4初学者,用到spring注解,log4j记录日志到文件

@Log注解获取日志

环境pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 主类开启AOP @EnableAspectJAutoProxy Log package com.entity; import java.lan.

qq_41835813的博客 1万+

STM32与威纶通触摸屏RS485通信实战:Modbus RTU协议与避坑指南

在工业自动化与嵌入式系统开发中,串行通信是实现设备间数据交换的基础技术。RS485总线凭借其差分信号传输、抗干扰能力强、支持多点通信及长距离传输等特性,成为工业现场广泛应用的物理层标准。其核心原理是利用一对双绞线进行平衡传输,有效抑制共模噪声。在协议层,Modbus RTU作为开放、简洁的主从式应用层协议,定义了统一的数据模型(如线圈、寄存器)和功能码,极大简化了不同厂商设备间的互操作性。结合STM32微控制器的UART外设与威纶通(Weinview)人机界面(HMI),可以构建稳定可靠的监控与控制系统。本

weixin_33925615的博客 327

测试人必看!正交表与Allpairs工具对比:如何选择最适合你的组合测试方案?

本文深入对比了正交表、PICT与Allpairs三种主流组合测试方案,帮助测试人员根据项目场景做出最佳选择。文章分析了各自的核心原理、优劣势及适用场景,特别强调了在涉及复杂约束时PICT工具的强大功能,并提供了从原理学习到CI/CD集成的实战选型指南。

weixin_29224309的博客 267

SpringBoot使用 AOP 实现自定义日志记录并保存在Mysql

主要定义了操作日志的一些基本的信息,用来对我们AOP自定义的日志进行存储。`user_id` int DEFAULT NULL COMMENT '用户名',`url` varchar(512) DEFAULT NULL COMMENT '接口',`ip` varchar(100) DEFAULT NULL COMMENT 'ip地址',`param` text COMMENT '接口参数',`time` datetime DEFAULT NULL COMMENT '时间',

喵小狸的博客 1485

linux下autocad完美替代品bricscad的安装运行

前言 在Linux平台下,能完美兼容.dwg文件的软件并不多。 虽然国产的中望和浩辰为适配uos操作系统,近期都推出了linux版本,但目前好像还没有对应的破姐流出。(如果有的话请私信我或留下评论) 然而有了这一款源自比利时的软件——bricscad,linux下查看和编辑.dwg文件再也不是噩梦了! 安装pj 资源链接:https://pan.baidu.com/s/1dC7zarlqwuO5fa4CBL_KGQ 提取码:24j6 1.下载对应的压缩包,解压并安装其中对应的deb或rpm软件包。 2.在C

weixin_35259117的博客 4478

【JAVA】SpringBoot通过自定义注解(AOP)优雅实现日志记录

在业务处理中,我们经常需要将一些用户操作、行为或系统日志记录到数据库中,并在后台做展示。一般情况下我们需要在每个需要进行记录的业务方法中做sql操作,这样一样日志记录这种非业务层面的代码就会和业务代码耦合,显得非常难看。那么有没有一种优雅记录日志的办法呢?当然是有的,以下介绍一种基于自定义注解的使用AOP来记录日志的办法。

weixin_44001652的博客 2678

XR Interaction Toolkit实战:为HTC Vive Cosmos打造抓取、投掷与UI交互(Unity 2023教程)

本文详细介绍了如何使用Unity 2023和XR Interaction Toolkit为HTC Vive Cosmos开发抓取、投掷与UI交互系统。通过实战案例'VR投掷训练室',从基础配置到高级功能实现,涵盖物理抓取、精准投掷机制和VR UI交互设计,帮助开发者提升VR交互开发技能。

weixin_30562507的博客 252

【WRF运行报错】总结WRF运行时报错及解决方案(持续更新)

总结WRF运行时报错及解决方案(持续更新)

WW、forever的博客 1629

SpringBoot项目如何优雅的实现操作日志记录

在实际开发当中,对于某些关键业务,我们通常需要记录该操作的内容,一个操作调一次记录方法,每次还得去收集参数等等,会造成大量代码重复。我们希望代码中只有业务相关的操作,在项目中使用注解来完成此项功能。通常就是使用Spring中的AOP特性来实现的,那么在SpringBoot项目当中应该如何来实现呢?...

Java升级之路的博客 3908

字节系,ali系,ks,pdd最新抓包方案

各大厂安卓逆向

qq_38759383的博客 1145

深入浅出:若依 (RuoYi) 框架 AOP 切片实现日志记录的原理与实践

若依框架通过 AOP 切面 + 自定义注解的方式,优雅地实现了操作日志记录功能。其核心思想是将日志记录这一横切关注点与业务逻辑解耦,通过注解标记需要增强的方法,在不侵入业务代码的前提下完成日志收集与存储。 这种实现方式不仅简化了日志功能的开发,还提高了代码的可维护性和扩展性,是 AOP 思想在实际项目中的典型应用。理解若依的日志切片实现,不仅能帮助我们更好地使用框架,还能为我们自己开发类似功能提供宝贵的参考。

lijingxiaov5的博客 2206

Microsemi Libero系列教程(六)——Identify片上逻辑分析仪的使用

文章目录FPGA如何进行在线调试关于Microsemi片上逻辑分析仪FPGA片上逻辑分析仪原理预期效果0.准备一个创建好的Libero工程1.新建identify工程,并添加想要监测的信号2.管脚分配,编译下载3.设置触发类型4.IICE逻辑分析仪核资源占用 系列教程:Microsemi Libero系列教程 FPGA如何进行在线调试 对于嵌入式系统来说,如单片机,进行硬件级程序调试时,通常采用的是JLink/ST-Link调试器,在线调试的方式来获取程序实时运行的状态,可以观察程序运行流程、各种变量的值

whik1194的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Spring AOP实现操作日志自动记录功能

在智慧社区管理系统中,操作日志记录是重要的审计功能。通过Spring AOP技术,实现了基于注解的自动日志记录功能,无需在每个方法中手动编写日志代码。// 操作描述// 操作类型开发效率: 通过注解自动记录,减少重复代码维护性: 集中管理日志逻辑,易于维护扩展性: 可以轻松添加新的日志字段性能: 异步记录,不影响主业务流程这种设计模式在企业级应用中非常实用,能够有效提升系统的可维护性和可审计性。

m0_62910542的博客 924

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Spring AOP结合@interface自定义注解实现日志记录

学习心得 系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 系列文章目录 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器...

fang.lovest.yang的博客 1240

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Spring Boot AOP记录用户操作日志

Spring Boot AOP记录用户操作日志 在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。首先搭建一个基本的Spring Boot Web环境开启Spring boot,然后引入必要依赖: <dependency> <groupId>org.springframework.boot</groupId> &l...

笙箫的博客 3479

通过自定义注解利用AOP在springmvc中实现记录日志

项目中需要记录用户操作日志,本文讲解使用的一种方法 1、导入所需jar包 除了spring相关jar包外,还需要引入aspectj包。 2、在配置文件中配置 在springmvc-servlet.xml中实现对AOP的支持 3、自定义注解 @Retention(RetentionPolicy.RUNTIME) @Target({ ElementT

飞龙在天 1830

springboot整合AOP实现操作日志记录功能

什么是AOP? AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP能够在方法的前置,中置,后置中插入逻辑代码,将逻辑独立于业务代码之外,一处编写,多处使用。 重点名词 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。 通知(Advice):切面必须要完成的工

三水沁 2480

Spring AOP 使用 SPEL 表达式记录日志

Spring AOP 使用 SPEL 表达式记录日志 需求来源 由于项目中需要记录操作日志,并且需要记录具体的细节操作,比如:新增用户,我们需要记录如下日志: 新增用户,用户名为:xxxx 获取参数xxxx的这个步骤,起始可以做到,但是一般做法是获取到方法的全部参数,这样记录的日志内容并不是很好看 所有我就想,会不会有支持 SPEL 表达式的方式,结果一百度,还真有,话不多说,现在记录下探索的过程...

小宇宙的博客 2182

Java实现@Log日志 - AOP技术

@Log的AOP实现

菜鸟博客 2496

使用 AOP + 自定义注解 实现 controller的日志打印

首先引入aop pom依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.8.RELEASE</version> <scope>compile</scope> </dependency

博博的博客 1134

使用自定义注解+spring aop实现日志记录

自定义注解实现日志记录 创建spring 项目 创建日志注解@Log package com.serendipity.annotation.annotation; import java.lang.annotation.*; /** * @Describe : 日志注解 * @Author : Serendipity * @Create : 2020/6/21 21:27 */ @Documented //生成文档 @Retention(RetentionPolicy.RUNTIME)// 注

qq_44004908的博客 314

Springboot自定义注解实现操作日志管理

操作日志的记录 为什么要有日志? 因为我们不光要记录代码的运行,如(logback log4j),而且还应该记录用户的行为,这叫做业务运行日志 例如:记录 zhangsan 在项目中 调用了哪个方法, 什么时间调用的 。访问的ip地址, 访问了哪些数据,做了什么操作,以此当程序出现问题的时候更利于我们进行错误的排查! 业务运行日志的作用 记录用户的行为 用于后续的分析 记录用户的所有的操作...

Java开发,人工智能,边缘计算,致力于掌握前沿技术 2521
上一篇: 【接口限流】基于注解Spring Boot 项目 + AOP + Redis 实现接口限流功能
下一篇: 【注解跳过机制】Spring Boot 登录权限校验拦截器教程
alan0721
博客等级 码龄10年 29粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值