AOP切面记录日志

news2024/11/28 9:15:23

AOP切面记录日志

一、导包

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

二、写一个注解

/**
 * 用于切面记录日志用的注解,只能加在方法中使用
 * @author ZHAOPINGAN
 */
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {
    // 可以在日志中记录该方法的信息,可加可不加
    String value() default "";
}

三、写一个AOP切面类,后面我会讲各个的含义

/**
 * 这是一个记录日志的aop切面
 * @author ZHAOPINGAN
 */
@Aspect
@Component
@Slf4j
public class Log {
    
	// 这里的知识点我后续会讲
    // @Pointcut 这是定义一个切点
    // 目前来说 这个方法没有用,因为我写的 controller 类的方法都是 public 
    // 我这里用了 private ,所以没有匹配的方法
    // 后续可以自己定义一个类的方法
    @Pointcut("execution(private * com.test.controller..*(..))")
    public void pt(){
    }
    // 这里面也可以塞注解
//    @Pointcut("@annotation(com.example.test.utils.MethodLog)")
//    	public void pt(){
//    }

    // 可以用上述的切点 , 也可以使用单个方法的注解记录日志
    // 这里使用了环绕通知,比 @Before 和 @After 更为强大
    // MethodLog 就是 二、写一个注解 中的注解
    @Around("pt() || @annotation(com.test.annotation.MethodLog)")
    public Object log(ProceedingJoinPoint joinPoint){
        Object proceed = null;
        // 获取 class 类,用于记录日志
        Class<?> aClass = joinPoint.getTarget().getClass();
        // 通过该 class 类 生成 Logger
        Logger logger = LoggerFactory.getLogger(aClass);
        try {
            // 获得方法签名(用于获取方法的信息)
            MethodSignature signature = (MethodSignature)joinPoint.getSignature();
            // 得到方法
            Method method = signature.getMethod();
            // 得到方法上面的注解
            MethodLog annotation = method.getAnnotation(MethodLog.class);
            // 如果方法中的 value 值不为空,就打印
            if (!StringUtils.isEmpty(annotation.value())){
                logger.info("{}",annotation.value());
            }
            // 输出请求参数
            Object[] args = joinPoint.getArgs();
            logger.info(signature.getName() + " 开始 请求参数的参数:{}", JSON.toJSONString(args));
            //执行方法
            proceed = joinPoint.proceed();
            // 输出返回值
            logger.info(signature.getName() + " 结束 返回值:{}",proceed);
        } catch (Throwable e) {
            logger.error("失败原因",e);
        }
        return proceed;
    }

}

@Pointcut参数含义

execution

execution(modifier? ret-type declaring-type?name-pattern(param-pattern) throws-pattern?)

表达式解释:

  • modifier:匹配修饰符,public, private 等,省略时匹配任意修饰符

  • ret-type:匹配返回类型,使用 * 匹配任意类型

  • declaring-type:匹配目标类,省略时匹配任意类型

    • … 匹配包及其子包的所有类
  • name-pattern:匹配方法名称,使用 * 表示通配符

    • * 匹配任意方法
    • set* 匹配名称以 set 开头的方法
  • param-pattern:匹配参数类型和数量

    • () 匹配没有参数的方法
    • (…) 匹配有任意数量参数的方法
    • (*) 匹配有一个任意类型参数的方法
    • (*,String) 匹配有两个参数的方法,并且第一个为任意类型,第二个为 String 类型
  • throws-pattern:匹配抛出异常类型,省略时匹配任意类型

根据上述,解析我写的
// 从后往前看
// com.test.controller..                  controller包下面所以的类
// com.test.controller..*                 controller包下面所以的类的所有方法
// com.test.controller..*(..)             controller包下面所以的类的所有方法且方法的参数随意
// * com.test.controller..*(..)           controller包下面所以的类的所有方法且方法的参数随意 返回值也随意
// private * com.test.controller..*(..))  controller包下面所以的类的所有方法且方法的参数随意 返回值也随意 但修饰符为private 
@Pointcut("execution(private * com.test.controller..*(..))")
public void pt(){
}

@annotation

@annotation(com.example.test.utils.MethodLog)

里面塞注解所在的类就可以了,我的也是塞得注解所在的类,这里就不多加赘述了

四、测试

@RestController
@Slf4j
public class TestController {
    @RequestMapping("/test2")
    @MethodLog
    public JSONObject test2(String id,String cid){
        log.info(id);
        log.info(cid);
        return EcpResponseUtil.success("成功","????????");
    }
}

在这里插入图片描述

参考博文:Spring AOP切点表达式(Pointcut)详解

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

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

相关文章

让性能腾飞!亚马逊云科技的 Java 云端之旅

在上篇文章中&#xff0c;我们为大家介绍了亚马逊的 Java 生态及丰富的开发工具、框架。本文将分享亚马逊的 Java 架构、迁移途径&#xff0c;并分享一个具体实例&#xff0c;介绍如何使用机器学习来构建 Java 应用和提升 Java 性能。 亚马逊云科技开发者社区为开发者们提供全…

vulhub-structs2-S2-009 远程代码执行漏洞复现

漏洞描述 影响版本: 2.1.0 - 2.3.1.1 漏洞原理 Struts2对s2-003的修复方法是禁止#号&#xff0c;于是s2-005通过使用编码\u0023或\43来绕过&#xff1b;于是Struts2对s2-005的修复方法是禁止\等特殊符号&#xff0c;使用户不能提交反斜线。 但是&#xff0c;如果当前action…

Java---第三章(选择,循环,二重循环语句,输入,调试,标签)

Java---第三章 一 流程图二 选择结构简单的if-else嵌套的if-else多重if的选择语句&#xff08;else-if&#xff09;switch语句 二 输入验证三 程序调试四 循环结构while循环do-while循环for循环流程控制二重循环&#xff08;重点&#xff09; 五 标签 label&#xff08;标号&am…

代码随想录二刷day27 | 回溯之 39. 组合总和 40.组合总和II 131.分割回文串

day27 39. 组合总和回溯三部曲剪枝优化 40.组合总和II回溯三部曲 131.分割回文串回溯三部曲判断回文子串 39. 组合总和 题目链接 解题思路&#xff1a; 本题没有数量要求&#xff0c;可以无限重复&#xff0c;但是有总和的限制&#xff0c;所以间接的也是有个数的限制。 本题搜…

AI对话分析,如何赋能销售人员实现销售增长和提升客户满意度?

在当今的商业世界中&#xff0c;销售人员的工作关键在于建立与潜在客户的关系&#xff0c;了解他们的需求&#xff0c;并提供满足这些需求的产品或服务。虽然这听起来简单&#xff0c;但实际上&#xff0c;这需要许多复杂的技能和经验。幸运的是&#xff0c;有许多工具和技术可…

消息队列及常见消息队列介绍

一、消息队列(MQ)概述 消息队列&#xff08;Message Queue&#xff09;&#xff0c;是分布式系统中重要的组件&#xff0c;其通用的使用场景可以简单地描述为&#xff1a; 当不需要立即获得结果&#xff0c;但是并发量又需要进行控制的时候&#xff0c;差不多就是需要使用消息队…

金属元素螯合剂:1189194-64-6,DOTA-(COOt-Bu)3-CH2-Alkynyl,试剂的结构式和CAS分享

文章关键词&#xff1a;双功能螯合剂&#xff0c;大环配体一、试剂基团反应特点&#xff08;Reagent group reaction characteristics&#xff09;&#xff1a; 西安凯新生物科技有限公司供应的​DOTA-(COOt-Bu)3-CH2-Alkynyl中&#xff0c;​DOTA分子是一种十二元四氮杂大环配…

【每日算法】【205. 同构字符串】

☀️博客主页&#xff1a;CSDN博客主页 &#x1f4a8;本文由 我是小狼君 原创&#xff0c;首发于 CSDN&#x1f4a2; &#x1f525;学习专栏推荐&#xff1a;面试汇总 ❗️游戏框架专栏推荐&#xff1a;游戏实用框架专栏 ⛅️点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd;&…

随机2D形状周围层流预测!基于飞桨实现图形神经网络

项目背景 近年来&#xff0c;快速流场预测领域一直由基于像素的卷积神经网络&#xff08;Convolution Neural Network&#xff0c;CNN&#xff09;主导。当 CFD 与基于 CNN 的神经网络模型耦合时&#xff0c;来自网格的数据必须在笛卡尔网格上进行插值&#xff0c;然后再投影回…

Jetpack Compose Material3 组件之 DatePicker(日期选择)

前言 在之前我使用 Comose 写 APP 的时候&#xff0c;官方还没有给出关于 DatePicker 的解决方案。 当时为了在 Compose 中实现 DatePicker &#xff0c;大致有两种方案&#xff1a; 一是使用原生 VIew 的 DatePicker&#xff0c;但是因为觉得我即然都用 Compose 了&#xf…

图书推荐|Python数据分析与挖掘实战(第2版)

Python数据分析与挖掘实战&#xff08;第2版&#xff09;一共分为三个部分&#xff0c;包括基础篇&#xff08;第1&#xff5e;5章&#xff09;、实战篇&#xff08;第6&#xff5e;12章&#xff09;、提高篇&#xff08;第13章&#xff09;。其中基础篇介绍了数据挖掘的基本原…

揭秘猫狗的微生物世界:肠道微生物群的意义和影响

谷禾健康 “铲屎官”们都希望自己的宠物有一个健康的身体。但是猫狗都不会说话&#xff0c;平时我们只能从它们的精神状态来判断它们是否健康&#xff0c;但这并不准确。去宠物医院又不太方便&#xff0c;很多猫咪和狗狗还会对抽血等检查有所抗拒。 肠道微生物检测在人类中的应…

边云协同:大小模型如何协同推理?

1 背景 “化繁为简、大巧不工”是机器学习的初衷之一。 费米曾讲述一个故事&#xff0c;冯诺依曼告诉他&#xff0c;用四个参数就可以拟合出一头大象&#xff0c;用五个参数就可以让大象鼻子动起来&#xff0c;这就是“四个参数画大象”的故事。 但AI模型规模不断剧增已是不…

CVE-2023-27524 Apache Superset 身份认证绕过漏洞

漏洞简介 Apache Superset是一个开源的数据可视化和数据探测平台&#xff0c;它基于Python构建&#xff0c;使用了一些类似于Django和Flask的Python web框架。提供了一个用户友好的界面&#xff0c;可以轻松地创建和共享仪表板、查询和可视化数据&#xff0c;也可以集成到其他应…

第一章 string模块

1. string模块介绍 Python中的第三方模块 string 模块解决了一些关于字符串操作的问题。例如&#xff0c;string 模块中可列出所有的大小写英文字母、数字、标点符号、八进制数字字符、十进制数字字符、十六进制数字字符等 Python 中可打印的字符&#xff1b;还可以进行格式化…

学习笔记之MySQL存储引擎

一、MySQL架构 MySQL的连接层处理客户端连接和权限管理&#xff0c;服务层解析和执行SQL语句&#xff0c;引擎层负责数据的存储和检索&#xff0c;存储层处理数据在磁盘上的读写操作。这种架构使得MySQL可以在不同的场景中灵活运行&#xff0c;并根据需求选择合适的存储引擎和…

Spring Security OAuth2.0认证授权 --- 基础篇

一、基本概念 1.1、什么是认证 进入移动互联网时代&#xff0c;大家每天都在刷手机&#xff0c;常用的软件有微信、支付宝、头条等&#xff0c;下边拿微信来举例子说明认证相关的基本概念&#xff0c;在初次使用微信前需要注册成为微信用户&#xff0c;然后输入账号和密码即可…

CVPR2022 多目标跟踪(MOT)汇总-补充篇

为该文章的后续补充https://blog.csdn.net/qq_34919792/article/details/124343166 七、《Multi-Object Tracking Meets Moving UAV》 作者: Shuai Liu†1, Xin Li†2, Huchuan Lu1,2, You He∗3 1Dalian University of Technology, 2Peng Cheng Laboratory, 3Naval Aeronaut…

【yolov5系列】将模型部署到瑞芯微RK3566上面

本篇博客记录将yolov5s移植到瑞芯微3566上的整体流程。当然在其它芯片上的操作类似&#xff0c;差别会在具体的API的调用上。 1 芯片相关 芯片参数&#xff1a;https://www.rock-chips.com/a/cn/product/RK35xilie/2021/0113/1273.htmlCPU&#xff1a;四核&#xff0c;1.8GHZ.N…

CSS查缺补漏之《选择器的复杂用法》

最近在复盘CSS基础知识&#xff0c;发现很多CSS选择器里面还是大有学问&#xff0c;需要详细总结一番&#xff0c;以备差缺补漏~ 作为CSS基础的一大类别&#xff0c;选择器又分为多种类别&#xff0c;本篇内容默认读者已了解并掌握基础选择器【通配符选择器】、【元素选择器】…