AOP实现日志记录需求

news2024/9/22 7:33:01

首先创建annotation包,包下创建SystemLog类

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

    String businessName();
}

创建aspect包,包下创建LogAspect类

@Component
@Aspect
@Slf4j
public class LogAspect {

    @Pointcut("@annotation(com.zzq.annotation.SystemLog)")
    public void pt() {

    }

    @Around("pt()")
    public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {

        Object ret ;
        try {
            handleBefore(joinPoint);
            ret = joinPoint.proceed();
            handleAfter(ret);
        } finally {
            //结束后换行
            log.info("=======End=======" + System.lineSeparator());


        }

        return ret;
    }

    private void handleAfter(Object ret) {
        // 打印出参
        log.info("Response      : {}",JSON.toJSONString(ret) );
    }

    private void handleBefore(ProceedingJoinPoint joinPoint) {


        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        //获取被增强方法上的注解对象
        SystemLog systemLog = getSystemLog(joinPoint);


        log.info("======= Start =======");
        // 打印请求 URL,增加空格使"URL:"和URL之间有一定间隔
        log.info("URL          : {}", request.getRequestURL());
        // 打印描述信息,同样增加空格
        log.info("BusinessName : {}", systemLog.businessName());
        // 打印 Http method,由于"HTTP Method"较长,可能需要更多空格来对齐
        log.info("HTTP Method  : {}", request.getMethod());
        // 打印调用 controller 的全路径以及执行方法,确保类名和方法名之间有适当的空格
        log.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
        // 打印请求的 IP
        log.info("IP           : {}", request.getRemoteHost());
        // 打印请求入参,如果参数较多或格式复杂,可能需要检查JSON.toJSONString的输出格式
        log.info("Request Args : {}", JSON.toJSONString(joinPoint.getArgs()));

    }

    private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        SystemLog systemLog = methodSignature.getMethod().getAnnotation(SystemLog.class);
        return systemLog;
    }
}

@Component: 这个注解表明 LogAspect 是一个 Spring 组件,Spring 容器会管理这个类的实例。在 Spring AOP 中,这通常意味着这个类会被 Spring 自动检测和注册为一个切面(Aspect)。

@Aspect: 这个注解表明 LogAspect 是一个切面类,它定义了一个或多个通知(Advice)和切点(Pointcut)。切面类负责将通知织入到目标对象中。

@Slf4j: 这是 Lombok 库提供的一个注解,用于自动生成一个名为 log 的日志对象,该对象通常是 org.slf4j.Logger 类型。这使得在类中的任何地方都可以直接使用 log 对象进行日志记录。

@Pointcut(“@annotation(com.zzq.annotation.SystemLog)”): 这个注解定义了一个切点表达式,它指定了哪些方法应该被增强。具体来说,任何被@com.zzq.annotation.SystemLog 注解标记的方法都将被这个切点捕获。pt() 方法本身没有实现体,它只是作为一个切点表达式的声明。
环绕通知(Around Advice)
@Around(“pt()”): 这个注解定义了一个环绕通知,它会在目标方法执行之前和之后执行。环绕通知接收一个 ProceedingJoinPoint 参数,这个参数代表了目标方法的执行点。通过调用 joinPoint.proceed(),可以执行目标方法,并获取其返回值。
printLog 方法是环绕通知的实现。它首先尝试执行 handleBefore 方法来记录一些前置信息(如请求的 URL、HTTP 方法、类名和方法名等),然后调用 joinPoint.proceed() 来执行目标方法,并将返回值存储在 ret 变量中。之后,它调用 handleAfter 方法来记录后置信息(如响应结果)。无论目标方法是否成功执行,finally 块中的代码都会执行,以记录日志的结束标记。

handleBefore 方法:这个方法在目标方法执行之前被调用,用于记录请求的相关信息,如请求的 URL、HTTP 方法、IP 地址、请求参数以及业务名称(从 @SystemLog 注解中获取)。

handleAfter 方法:这个方法在目标方法执行之后被调用,用于记录响应结果。它使用 JSON.toJSONString(ret) 将响应结果转换为 JSON 字符串,并记录到日志中。

getSystemLog 方法:这个方法用于从目标方法上获取 @SystemLog 注解实例。它通过 joinPoint.getSignature() 获取到 MethodSignature,然后调用 getMethod() 获取到 Method 对象,最后从该对象上获取注解实例。

最后在方法中加入中

在这里插入图片描述

最后效果展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2054452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

给RAG系统做一次全面「体检」,亚马逊开源RAGChecker诊断工具

亚马逊上海人工智能研究院成立于 2018 年,已成为深度学习研究领域的领先机构之一,共发表了~90 篇论文。研究领域包括深度学习的基础理论、自然语言处理、计算机视觉、图机器学习、高性能计算、智能推荐系统、欺诈检测与风险控制、知识图谱构建…

【Redis分析】(一) 主从同步

主从复制 - 数据备份, 读写分离, 手动高可用 负载均衡: 主结点只负责处理写请求, 从节点负责读请求;主从复制, 主机挂了, 我们可以手动切换从机, 还可以搭配哨兵实现自动切换, 实现高可用;需要注意的是, 在主从模式下, 假设进行同步的过程中主节点宕机了, 那么从节点此时还没有…

Ubuntu | 右上角网络图标消失,有线网络在设置中消失,虚拟机没网

目录 第一步:删除 NetworkManager 缓存文件第二步:修改 /etc/NetworkManager/NetworkManager.conf第三步:重启 NetworkManager第四步:右上角网络图标出现 参考博客:虚拟机没网,重启网络服务:Fai…

手机操作技巧:如何进入锁定的Android手机

被锁定在您的 Android 手机之外可能是一种令人沮丧的经历,尤其是当您存储了重要文件和数据时。幸运的是,您可以尝试几种方法来重新获得对手机的访问权限。在这篇博文中,我们将探讨可用于解锁锁定的 Android 手机的各种技术和工具。我们还将提…

80.游戏的分辨率修改思路与分析

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:易道云信息技术研究院 上一个内容:79.游戏分析工具闪屏问题优化与数据被修改高亮 GAMEHACKER2.exe 工具下载地址&#xff…

Neo4j图数据库Docker部署至服务器

Neo4j图数据库Docker部署至服务器 文章目录 Neo4j图数据库Docker部署至服务器1. Neo4j介绍2. 拉取Docker镜像3. 创建容器并运行4. 导入数据(可选)5. 访问测试 1. Neo4j介绍 Neo4j 是一种基于图数据库管理系统,它专门用于存储和查询图数据结构…

Vuepress,搭建自己的技术文档

Vuepress Vuepress用于构建静态站点,非常适合搭建技术文档。如果手头上有开源项目,或者公司内部有项目需要做官网,且官网中大部分都是介绍、用法之类的文章。那么Vuepress是不二选择! 我们看到的一些项目的技术文档,…

河北学术会议:机器视觉、图像处理与影像技术领域

第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)将于2024年9月13日-15日在中国张家口召开。MVIPIT2024聚焦机器视觉、图像处理与影像技术,旨在为专家、学者和研究人员提供一个国际平台,分享研究成果,讨论问题…

WebSocket可拓展业务组件搭建,无侵入实现WebSocket通信信息自定义业务消费

组件概述 面对C端产品,往往会携带有客户端和服务端的双端通信以实现实时交互的效果,但是目前HTTP1.1并不支持双端通信,因此,对于聊天室、多人实时游戏等场景,就需要用到一个新的通信协议:WebSocket。 更多…

UE5-C++入门教程(二)---编写Editor类别的自定义模型实现小球规划路线的可视化

前言 本教程将以图文教程的形式讲述如何快速入门通过C使用UE5.4进行项目编写。UE5的教程系列 第一期:UE5-C入门教程(一):使用代码创建一个指定目标的移动小球-CSDN博客 UE5与ROS2实战->基于UE5和ROS2的激光雷达深度RGBD相机小车的仿真指南(一)—Unre…

MoneyPrinterTurbo的部署,在服务器Ubuntu22.04系统下——点动科技

在服务器Ubuntu22.04系统下,MoneyPrinterTurbo的部署 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表:2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有驱动2.3 安装驱动2.4…

Axure高端交互元件库:助力产品与设计

用户体验(UX)和用户界面(UI)设计对于任何产品的成功都至关重要。为了在这个竞争激烈的市场中脱颖而出,设计师和产品开发团队需要依赖强大的工具来创造引人注目且功能丰富的交互界面。下面介绍一款Axure精心制作的"…

物联网(IoT)详解

物联网(IoT)详解 1. IoT定义简介2. IoT工作原理3. IoT关键技术4. 物联网与互联网区别5. IoT使用场景6. 开源物联网平台7. 参考资料 1. IoT定义简介 首先第一个问题,什么是物联网(IoT)? 物联网(英文&#…

Linux:CentOS配置

一,安装VMware 这个可以通过官网获取 vmware下载 也可以联系我,我发给你 二,安装CentOS Centos官网找要下载的版本: https://vault.centos.org/ 阿里云镜像:https://mirrors.aliyun.com/centos-vault/?spma2c6h.13…

如何搭建redis哨兵集群

1. 构建redis镜像 FROM redis:7.0.15-alpine3.20# install tools RUN apk add curl --no-cache &&\apk add bash --no-cache # COPY redis.conf /usr/local/etc/redis/redis.confCMD [ "redis-server", "/usr/local/etc/redis/redis.conf"] dock…

一起学习LeetCode热题100道(45/100)

45.二叉树的右视图(学习) 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 示例 2: 输入: [1,null,3] 输出: [1,3] 示例 …

【微信小程序】自定义组件 - 数据、方法和属性

1. data 数据 2. methods 方法 在小程序组件中,事件处理函数和自定义方法需要定义到 methods 节点中,示例代码如下: 3. properties 属性 在小程序组件中,properties 是组件的对外属性,用来接收外界传递到组件中的数…

如何使用docker打包后端项目并部署到阿里云k8s集群上

如何使用docker打包后端项目并部署到阿里云k8s集群上 1. 引言 在现代软件开发中,容器化技术已经成为主流,而Kubernetes (K8s) 是管理容器的首选平台之一。本文将详细介绍如何将一个后端项目使用Docker打包,并将其部署到阿里云的Kubernetes集群上。 2. 前置条件 阿里云账号…

sentinel集成springcloud实现限流熔断

Sentinel 是由阿里巴巴开源的一款流量控制和熔断降级组件,旨在通过灵活的流量控制和熔断降级机制,帮助开发者保护微服务架构中的应用和服务。 官网:home | Sentinel (sentinelguard.io) 一、安装sentinel 1.方式一:用docker-compose 安装 docker-com…

回归预测|基于粒子群优化深度神经网络DNN的数据回归预测Python程序PSO-DNN 多特征输入单输出

回归预测|基于粒子群优化深度神经网络DNN的数据回归预测Python程序PSO-DNN 多特征输入单输出 文章目录 前言回归预测|基于粒子群优化深度神经网络DNN的数据回归预测Python程序PSO-DNN 多特征输入单输出 一、PSO-DNN模型1. 粒子群优化(PSO)简介2. 深度神经…