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

Springboot自定义注解

在Spring Boot项目中,通过自定义注解和AOP实现方法执行前后的日志记录,可以按照以下步骤操作:

步骤 1:添加依赖

确保pom.xml中包含AOP依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

步骤 2:创建自定义注解

定义@Loggable注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
}

步骤 3:实现AOP切面

创建切面类处理日志逻辑:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Component
public class LoggingAspect {

    private final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Around("@annotation(Loggable)")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String className = signature.getDeclaringType().getSimpleName();
        String methodName = signature.getName();
        Object[] args = joinPoint.getArgs();

        // 记录方法入参
        logger.info(">>> 方法 {}.{} 入参: {}", className, methodName, Arrays.toString(args));
        try {
            long startTime = System.currentTimeMillis();
            
            // 执行目标方法
            Object result = joinPoint.proceed();
            
            long elapsedTime = System.currentTimeMillis() - startTime;
            
            // 记录返回结果和执行时间
            logger.info("<<< 方法 {}.{} 耗时: {} ms, 返回值: {}",
                    className,
                    methodName,
                    elapsedTime,
                    objectMapper.writeValueAsString(result));
            
            return result;
        } catch (Throwable e) {
            // 记录异常信息
            logger.error("!!! 方法 {}.{} 异常: {}", className, methodName, e.getMessage(), e);
            throw e;
        }
    }
}

步骤 4:使用注解

在需要监控的方法上添加@Loggable

@RestController
@RequestMapping("/api/aop")
public class AopController {


    @GetMapping("getResult/{param}")
    @Loggable
    public ResponseEntity<String> getResult(@PathVariable("param") String param){

        return new ResponseEntity<>("12345678", HttpStatus.OK);
    }
}

高级配置建议

  1. 敏感信息过滤:在序列化前排除敏感字段。
  2. 性能优化:添加条件判断,仅在调试模式记录完整日志。
  3. 异步日志:使用异步Appender提升性能。
  4. 自定义序列化:对特定类型定制序列化方式。

执行效果示例

2025-03-06 22:39:36.646  INFO 5268 --- [nio-8080-exec-3] com.sh.system.config.LoggingAspect       : >>> 方法 AopController.getResult 入参: [123]
2025-03-06 22:39:36.659  INFO 5268 --- [nio-8080-exec-3] com.sh.system.config.LoggingAspect       : <<< 方法 AopController.getResult 耗时: 2 ms, 返回值: {"headers":{},"body":"12345678","statusCode":"OK","statusCodeValue":200}

接口调用
在这里插入图片描述

注意事项

  1. 确保Spring Boot版本 ≥ 2.x
  2. 复杂对象需实现toString()或配置Jackson序列化
  3. 内部方法调用需通过代理对象执行

以上实现会完整记录方法执行的输入参数、返回结果和执行耗时,异常时会记录堆栈跟踪信息。

相关文章:

  • C++进阶(八)--C+11
  • CES Asia 2025:5G与物联网成焦点,论坛峰会引企业关注
  • 前端开发基石:HTML语义化深度解析与实践指南
  • DFS学习笔记
  • 【C++】二叉树相关算法题
  • 【Linux】信号处理以及补充知识
  • 常见面试问题:MVC模式
  • Jenkins学习笔记
  • 笔记:在Git中.gitmodules文件的功能和作用和如何使用
  • spdlog 生成日志
  • 从零开始在Windows使用VMware虚拟机安装黑群晖7.2系统并实现远程访问
  • .NET 10首个预览版发布:重大改进与新特性概览!
  • 从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十三) 优化聊天页面
  • 《机器学习数学基础》补充资料:过渡矩阵和坐标变换推导
  • 华为OD最新机试真题-模拟目录管理-C++-OD统一考试(E卷)
  • R语言和RStudio安装
  • 自学Java-JavaSE基础加强(多线程)
  • 计算机毕设-基于springboot的物流管理系统的设计与实现(附源码+lw+ppt+开题报告)
  • 60页PDF | 四川电信数据湖及数据中台实施方案!(附下载)
  • Spring Boot 3.x 核心注解详解与最佳实践
  • 深圳网站建设 东莞网站建设/软文营销代理
  • 电子政务网站建设出版社/推广方案策划
  • 巨量广告投放平台/奉化网站关键词优化费用
  • 企业宣传网站建设/投诉百度最有效的电话
  • java建设网站的步骤/北京企业网站推广哪家公司好
  • 网上学编程靠谱吗/武汉seo管理