springboot 注解实现AOP记录日志

2023-11-12

AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。在日常开发当中经常用来记录日志,方法跟踪、事务,权限等

切面方法说明:

  •  @Aspect -- 作用是把当前类标识为一个切面供容器读取
  • @Pointcut -- (切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
  • @Before -- 标识一个前置增强方法,相当于BeforeAdvice的功能
  • @AfterReturning -- 后置增强,相当于AfterReturningAdvice,方法退出时执行
  • @AfterThrowing -- 异常抛出增强,相当于ThrowsAdvice
  • @After -- final增强,不管是抛出异常或者正常退出都会执行
  • @Around -- 环绕增强,相当于MethodInterceptor 

 

引入AOP依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

定义一个切面--TestAspect

@Aspect

@Component

@Slf4j

public class TestAspect {


//com.kzj.kzj_rabbitmq.controller 包中所有的类的所有方法切面

//@Pointcut("execution(public com.kzj.kzj_rabbitmq.controller..(..))")


//只针对 MessageController 类切面

//@Pointcut("execution(public com.kzj.kzj_rabbitmq.controller.MessageController.(..))")


//统一切点,对com.kzj.kzj_rabbitmq.controller及其子包中所有的类的所有方法切面

@Pointcut("execution(public com.kzj.kzj_rabbitmq.controller...(..))")

public void Pointcut() {

}


//前置通知

@Before("Pointcut()")

public void beforeMethod(JoinPoint joinPoint){

log.info("调用了前置通知");


}


//@After: 后置通知

@After("Pointcut()")

public void afterMethod(JoinPoint joinPoint){

log.info("调用了后置通知");

}

//@AfterRunning: 返回通知 rsult为返回内容

@AfterReturning(value="Pointcut()",returning="result")

public void afterReturningMethod(JoinPoint joinPoint,Object result){

log.info("调用了返回通知");

}

//@AfterThrowing: 异常通知

@AfterThrowing(value="Pointcut()",throwing="e")

public void afterReturningMethod(JoinPoint joinPoint, Exception e){

log.info("调用了异常通知");

}


//@Around:环绕通知

@Around("Pointcut()")

public Object Around(ProceedingJoinPoint pjp) throws Throwable {

log.info("around执行方法之前");

Object object = pjp.proceed();

log.info("around执行方法之后--返回值:" +object);

return object;

}


}

添加测试用Controller​​​​​​​

@RestController

@Slf4j

public class MessageController {


@RequestMapping(value="/send_message",produces = "text/json;charset=UTF-8")

public String send_message(MessagePojo pojo) throws Exception {

log.info("执行了controller.send_message方法");

return JSON.toJSONString(pojo);

}

}

测试:

在浏览器输入:http://localhost:9999/send_message?delay=15&className=B</a></p>

可看到打印

可以看到,aspect类内部的 advice 将按照以下的顺序进行执行

one-ok

下面是项目中实战-使用AOP打印日志和效率监听(记录请求参数和返回结果和方法运行总时间)​​​​​​​

@Aspect

@Component

@Slf4j

public class TestAspect {


//com.kzj.kzj_rabbitmq.controller 包中所有的类的所有方法切面

//@Pointcut("execution(public com.kzj.kzj_rabbitmq.controller..(..))")


//只针对 MessageController 类切面

//@Pointcut("execution(public com.kzj.kzj_rabbitmq.controller.MessageController.(..))")


//统一切点,对com.kzj.kzj_rabbitmq.controller及其子包中所有的类的所有方法切面

@Pointcut("execution(public com.kzj.kzj_rabbitmq.controller...(..))")

public void Pointcut() {

}



//@Around:环绕通知

@Around("Pointcut()")

public Object Around(ProceedingJoinPoint pjp) throws Throwable {

Map<String,Object> data = new HashMap<>();

//获取目标类名称

String clazzName = pjp.getTarget().getClass().getName();

//获取目标类方法名称

String methodName = pjp.getSignature().getName();


//记录类名称

data.put("clazzName",clazzName);

//记录对应方法名称

data.put("methodName",methodName);

//记录请求参数

data.put("params",pjp.getArgs());

//开始调用时间

// 计时并调用目标函数

long start = System.currentTimeMillis();

Object result = pjp.proceed();

Long time = System.currentTimeMillis() - start;


//记录返回参数

data.put("result",result);


//设置消耗总时间

data.put("consumeTime",time);

System.out.println(data);

return result;


}


}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot 注解实现AOP记录日志 的相关文章

  • SAML 服务提供商 Spring Security

    当使用预先配置的服务提供者元数据时 在 Spring Security 中 是否应该有 2 个用于扩展元数据委托的 bean 定义 一份用于 IDP 元数据 一份用于 SP 元数据
  • Java:如何从转义的 URL 获取文件?

    我收到了一个定位本地文件的 URL 事实上我收到的 URL 不在我的控制范围内 URL 按照 RFC2396 中的定义进行有效转义 如何将其转换为 Java File 对象 有趣的是 URL getFile 方法返回一个字符串 而不是文件
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • 运行具有外部依赖项的 Scala 脚本

    我在 Users joe scala lib 下有以下 jar commons codec 1 4 jar httpclient 4 1 1 jar httpcore 4 1 jar commons logging 1 1 1 jar ht
  • Cassandra java驱动程序协议版本和连接限制不匹配

    我使用的java驱动程序版本 2 1 4卡桑德拉版本 dsc cassandra 2 1 10cql 的输出给出以下内容 cqlsh 5 0 1 Cassandra 2 1 10 CQL spec 3 2 1 Native protocol
  • 如何安全地解决这个 Java 上下文类加载器问题?

    我的数百名用户中只有一位在启动我的 Java 桌面应用程序时遇到问题 他只有大约三分之一的时间开始 另外三分之二的时间在启动时抛出 NullPointerException Exception in thread AWT EventQueu
  • 画透明圆,外面填充

    我有一个地图视图 我想在其上画一个圆圈以聚焦于给定区域 但我希望圆圈倒转 也就是说 圆的内部不是被填充 而是透明的 其他所有部分都被填充 请参阅这张图片了解我的意思 http i imgur com zxIMZ png 上半部分显示了我可以
  • Java 8 流 - 合并共享相同 ID 的对象集合

    我有一系列发票 class Invoice int month BigDecimal amount 我想合并这些发票 这样我每个月都会收到一张发票 金额是本月发票金额的总和 例如 invoice 1 month 1 amount 1000
  • 使用 SQLITE 按最近的纬度和经度坐标排序

    我必须获得一个 SQLite SQL 语句 以便在给定初始位置的情况下按最近的纬度和经度坐标进行排序 这是我在 sqlite 数据库中的表的例句 SELECT id name lat lng FROM items EXAMPLE RESUL
  • 使用过滤器@ComponentScan所有包的危险

    我现在正在开发一个概念应用程序 我想使用组件扫描来使用特定的自定义 Spring 元注释来获取类路径上任何位置的所有类 我的注释如下所示 Target value ElementType TYPE Retention value Reten
  • 如何知道抛出了哪个异常

    我正在对我们的代码库进行审查 有很多这样的陈述 try doSomething catch Exception e 但我想要一种方法来知道 doSomething 抛出了哪个异常 在 doSomething 的实现中没有 throw 语句
  • 考虑在配置中定义“org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder”类型的 bean

    我正在尝试将 jwt 令牌连接到我的项目 但在工作过程中遇到了一些问题 我已按照上述说明进行操作here https auth0 com blog implementing jwt authentication on spring boot
  • 在 Spring 中重构这个的最佳方法?

    private final ExecutorService executorParsers Executors newFixedThreadPool 10 public void parse List
  • Netty:阻止调用以获取连接的服务器通道?

    呼吁ServerBootstrap bind 返回一个Channel但这不是在Connected状态 因此不能用于写入客户端 Netty 文档中的所有示例都显示写入Channel从它的ChannelHandler的事件如channelCon
  • javafx android 中的文本字段和组合框问题

    我在简单的 javafx android 应用程序中遇到问题 问题是我使用 gradle javafxmobile plugin 在 netbeans ide 中构建了非常简单的应用程序 其中包含一些文本字段和组合框 我在 android
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • Trie 数据结构 - Java [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有任何库或文档 链接提供了在 java 中实现 Trie 数据结构的更多信息 任何帮助都会很棒 Thanks 你可以阅读Java特里树

随机推荐

  • 漏洞扫描是什么?怎么做?

    漏洞扫描 漏洞扫描是指基于漏洞数据库 通过扫描等手段对指定的远程或者本地计算机系统的安全脆弱性进行检测 发现可利用漏洞的一种安全检测 渗透攻击 行为 漏洞扫描按扫描器所处位置 可分为内网扫描和外网扫描 而按照工作方式 又可以将漏洞扫描分为远
  • 【SpringBoot项目实战】图片压缩包上传、解压、存储等等一套流程教学

    SpringBoot项目实战 图片压缩包上传 解压 存储等等一套流程教学 前言 一 压缩包上传 1 接口实现 2 获取压缩包的文件名和文件路径 二 压缩包解压并保存 1 处理压缩包文件方法 解压缩步骤 2 接口中实现处理压缩包 三 总结 前
  • HTML在工作中的使用

    本文是在学习HTML的时候 心血来潮尝试的做法 纯属瞎玩 不可当真 示例 工作中编辑邮件 在管理系统上进行任务编辑 描述时 都可能会使用到HTML的简单知识 有一些简单的标签可以帮助我们更好的完成工作 比如字体加粗 换行等 比如我在办公系统
  • python使用装饰器记录方法耗时

    思路 python使用修饰器记录方法耗时 目的是每当方法执行完后 可以记录该方法耗时 而不需要在每个方法的执行前后 去创建一个临时变量 来记录耗时 方式一 不推荐 在每个方法的执行前后 去创建一个临时变量 来记录耗时 代码如下 缺点在于 如
  • 爱好高科技之人脸识别模块

    前段时间看到一款性价比很不错的人脸识别模组 2个关键指标引起了我极大的兴趣 1 99 的识别通过率 误识率低于百万分之一 2 双目摄像头 活体检测 于是买了几个 结合离线语音模块 两者通过串口进行一问一答通信 人机交互部分通过语音和OLED
  • 运行vue-admin-template和vue-element-admin及可能问题点解决

    系统 windows10 64位 需求 安装node js git客户端 ssh公钥设定好 安装node sass 前提 安装好node js 配置好环境 安装好的nodejs文件夹下如下图所示 其中node global和node cac
  • Java21天打卡Day8-break

    break和continue break 表示跳出当前层循环 continue 表示跳出本次循环 进入下一次循环 import com sun org apache xerces internal util SynchronizedSymb
  • vue 项目放弃“tui-editor“ “1.3.3“,

    从官网https github com PanJiaChen vue element admin下载的版本带有 tui editor 版本1 3 3 在编译时会遇到如下问题 error An unexpected error occurre
  • 使用 X2MindSpore 迁移 Pytorch 训练脚本mobileNet支持分布式训练

    简介 MindSpore是华为昇腾开发的深度学习框架 旨在提供端边云全场景的AI框架 Pytorch是由Facebook推出的AI框架 本教程使用MindStudio中的X2MindSpore功能自动将Pytorch脚本转换为MindSpo
  • 整数的逆序数

    本题要求实现一个求整数的逆序数的简单函数 函数接口定义 int reverse int number 其中函数reverse须返回用户传入的整型number的逆序数 include
  • 解决warning: this statement may fall through [-Wimplicit-fallthrough=]

    使用switch如果缺少break gcc编译的时候会报相关的warnning信息 如果是忘记写 这样肯定是有问题的 警告信息可以帮助我们排除隐藏的bug 要消除警告很简单 把break加上就行 但是有时候 我们的需求就是需要继续向下执行
  • 计算曲线与坐标轴的面积

    根据坐标点 计算曲线与坐标轴的面积 import numpy as np import matplotlib pyplot as plt x np arange 0 1 0 001 y np sqrt 1 x 2 plt close all
  • STM32F4通过U盘升级程序

    昨天的文章中介绍F4系列单片机的内部Flash读写 包括之前文章中介绍了FatFS文件系统读写U盘的操作 本篇文章就是将两者结合 实现F4系列单片机程序的U盘升级 首先对内部Flash空间进行划分 前128K用于存储BootLoader程序
  • chatgpt login进不去的原因和解决办法!

    chatgpt官网在国内是打不开的 可以说是双向封闭 1 由于国内实施了网络审查和防火墙措施 访问特定的网站会受到限制主要是针对服务器设置到境外的网站 为了确保网络安全和政策合规性防火墙会屏蔽包含敏感内容或违反相关规定的网站或服务 以确保网
  • Cadence OrCAD原理图如何统计元件管脚总数量

    Cadence OrCAD原理图如何统计元件管脚总数量 本章节教大家如何在Cadence OrCAD原理图如何统计元件管脚总数量 操作方法 1 打开原理图文件 File Open Design 2 鼠标单击选中根目录下DSN文件夹 右键选择
  • ajax 用户验证js,js ajax验证用户名

    回答 jQuery的ajax 验证用户名的例子 验证用户名 js 方法 uname 输入的用户名 function ajax check uname uname var url check uname php 这里是你的php post u
  • Vue3 框架使用报错以及解决办法

    1 TypeError Failed to fetch dynamically imported module 引入组件时 没有添加 vue后缀 或者引入的组建没有被使用 2 SyntaxError The requested module
  • IntelliJ IDEA更新Maven远程仓库索引index(pom文件终于有快速的自动提示了)

    IntelliJ IDEA更新Maven远程仓库索引 因为某些原因 在 IDEA 下载 Maven 索引总是特别慢 有时候等待它下载好几个小时 然后突然抽风下载失败 再下载又要重新下了 所以这里介绍从远程下载索引到本地更新的方法 本文默认你
  • 遍历实体包含的List

    for ShopGoodSpec s shopgood getSpecs s setGoods id shopgood getGoods id
  • springboot 注解实现AOP记录日志

    AOP AOP为Aspect Oriented Programming的缩写 意为 面向切面编程 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 在日常开发当中经常用来记录日志 方法跟踪 事务 权限等 切面方法说明 Aspe