AOP案例
黑马程序员JavaWeb开发教程
文章目录
- 一、案例
- 1.1 案例
- 1.2 步骤
- 1.2.1 准备
- 1.2.2 编码
一、案例
1.1 案例
- 将之前案例中增、删、改相关节后的操作日志记录到数据库表中。
- 操作日志:日志信息包含:操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值、方法执行时长
- 思路分析
- 需要对所有业务中的增、删、改方法添加同一功能,使用AOP技术最为方便,@Around 环绕通知
- 由于增、删、改方法名没有规律,可以自定义@Log 注解完成目标方法匹配
1.2 步骤
1.2.1 准备
- 在案例工程中引入AOP的起步依赖
<!-- AOP起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
- 在数据库中新建日志数据表,并引入对应的实体类
- 创建数据表语句
-- 操作日志表
create table operate_log(id int unsigned primary key auto_increment comment 'ID',operate_user int unsigned comment '操作人ID',operate_time datetime comment '操作时间',class_name varchar(100) comment '操作的类名',method_name varchar(100) comment '操作的方法名',method_params varchar(1000) comment '方法参数',return_value varchar(2000) comment '返回值',cost_time bigint comment '方法执行耗时, 单位:ms'
) comment '操作日志表';
- 实体类代码
package com.itheima.mytlias.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigInteger;
import java.time.LocalDateTime;//操作日志表
@Data//getter、setter等
@NoArgsConstructor//无参构造函数
@AllArgsConstructor//全参构造函数
public class OperateLog {private Integer id;//idprivate Integer operateUser;//操作人idprivate LocalDateTime operateTime;//操作时间private String className;//操作的类名private String methodName;//操作的方法名private String methodParas;//方法参数private String returnValue;//返回值private BigInteger costTime;//方法执行时间,单位ms
}
- 另外还需要mapper接口,以向日志记录表中插入数据
package com.itheima.mytlias.mapper;import com.itheima.mytlias.pojo.OperateLog;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface OperateLogMapper {@Insert("insert into operate_log(operate_user,operate_time,class_name,method_name,method_params,return_value,cost_time) values(#{operateUser},#{operateTime},#{className},#{methodName},#{methodParams},#{returnValue},#{costTime})")public void insert(OperateLog operateLog);
}
获取当前登录用户
:获取request对象,从轻去偷中获取到jwt令牌,解析令牌获取出当前用户的id
1.2.2 编码
- 自定义注解@Log
- 在com.itheima.mytilas 包下新建包 anno,创建注解 @Log
package com.itheima.mytlias.anno;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
}
- 定义切面类,完成记录操作日志的逻辑
package com.itheima.mytlias.aop;import com.alibaba.fastjson.JSONObject;
import com.itheima.mytlias.mapper.OperateLogMapper;
import com.itheima.mytlias.pojo.OperateLog;
import com.itheima.mytlias.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;@Slf4j//日志
@Component//交给IOC容器管理
@Aspect//切面类
public class LogAspect {//为了拿到当前这次请求的请求头对象,我们直接注入一个HttpServletRequest 对象@AutowiredHttpServletRequest request;//调用mapper接口中的insert方法记录日志,因此注入一个OperateLogMapper对象@AutowiredOperateLogMapper operateLogMapper;@Around("@annotation(com.itheima.mytlias.anno.Log)")public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {//操作人id(通过获取请求头张的jwt令牌来解析令牌)String jwt = request.getHeader("token");Claims claims = JwtUtils.parseJWT(jwt);//使用JWT工具类解析jwt令牌Integer operateUser = (Integer) claims.get("id");//操作用户的idlog.info("用户id,{}", operateUser);//操作时间LocalDateTime operateTime = LocalDateTime.now();//操作的类名String className = proceedingJoinPoint.getTarget().getClass().getName();// 操作的方法名String methodName = proceedingJoinPoint.getSignature().getName();// 操作的方法参数Object[] args = proceedingJoinPoint.getArgs();String methodParms = Arrays.toString(args);//调用方法之前的时间(用于计算方法运行耗时)long begin = System.currentTimeMillis();//调用原始目标方法Object result = proceedingJoinPoint.proceed();//调用方法之后的时间(用于计算方法运行耗时)long end = System.currentTimeMillis();// 返回值String returnValue = JSONObject.toJSONString(result);// 操作耗时long costTime = (end - begin);//记录操作日志OperateLog operateLog = new OperateLog(null, operateUser, operateTime, className, methodName, methodParms, returnValue, costTime);operateLogMapper.insert(operateLog);//在控制打印输出日志log.info("AOP记录操作日志:{}", operateLog);//返回值return result;}
}
- 在所有增删改的方法上加上注解@Log
相关文章:

AOP案例
黑马程序员JavaWeb开发教程 文章目录 一、案例1.1 案例1.2 步骤1.2.1 准备1.2.2 编码 一、案例 1.1 案例 将之前案例中增、删、改相关节后的操作日志记录到数据库表中。 操作日志:日志信息包含:操作人、操作时间、执行方法的全类名、执行方法名、方法…...
Facebook海外户Facebook广告被暂停的原因
有很多伙伴在Facebook广告时,有时会遇到账号被暂停,并通知你违反了哪些规则,那么Facebook广告被暂停的原因有哪些呢?今天小编详细梳理了一些原因,可以往下看哦~ 您的Facebook广告被暂停可能有以下几个原因:…...
网站企业需要适用于什么服务器?
对于网站企业会选择什么样的服务器呢? 为了保证网站能够稳定的运行需要选择高可用性和可靠性的网站服务器,选择具备高可用性架构的云服务器供应商,能够提供多可用区部署、自动故障转移和备份恢复等功能,保障网站在各种故障情况下的…...

winscp无法上传,删除,修改文件并提示权限不够的分析
使用winscp删除文件,报了个错如下 根据这个错就去百度,网上大部分都是通过下面这种方法解决: 在winscp端进行设置 输入主机名(即IP地址)、用户名和密码,然后点击高级 在箭头所指位置输入sudo + sftp应用程序的路径 先查询 sudo find / -name sftp-server -print点击Sh…...

Hadoop3:MapReduce之InputFormat数据输入过程整体概览(0)
一、MapReduce中数据流向 二、MapTask并行度 1、原理概览 数据块:Block是HDFS物理上把数据分成一块一块。数据块是HDFS存储数据单位。 数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。数据切片是MapRed…...
【Leetcode Python】70.爬楼梯
麻烦大家要自己去leetcode看题目 第一个思路 用递归会超时 return self.climbStairs(n - 1) self.climbStairs(n - 2)第二个思路 滚动数组思想 class Solution(object):def climbStairs(self, n):""":type n: int:rtype: int"""if(n<2)…...
深度学习 - 张量的广播机制和复杂运算
张量的广播机制(Broadcasting)是一种处理不同形状张量进行数学运算的方式。通过广播机制,PyTorch可以自动扩展较小的张量,使其与较大的张量形状兼容,从而进行元素级的运算。广播机制遵循以下规则: 如果张量…...
【CSS】will-change 属性详解
目录 基本语法属性值常见用途will-change 如何用于优化动画效果示例: will-change 是一个 CSS 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化渲染性能,提前做一些准备工作,从而提高性能。 基本语法…...

linux安装mysql后,配置mysql,并连接navicat软件
Xshell连接登陆服务器 输入全局命令 mysql -u root -p 回车后,输入密码,不显示输入的密码 注意mysql服务状态,是否运行等 修改配置文件my.cnf,这里没找到就找my.ini,指定有一个是对的 find / -name my.cnf 接下…...
【学习笔记】Axios、Promise
TypeScript 1、Axios 1.1、概述 1.2、axios 的基本使用 1.3、axios 的请求方式及对应的 API 1.4、axios 请求的响应结果结构 1.5、axios 常用配置选项 1.6、axios.create() 1.7、拦截器 1.8、取消请求2、Promise 2.1、封装 fs 读…...
自然资源-关于加强规划实施监督管理的指导意见(浙江省自然资源厅学习借鉴)
自然资源-关于加强规划实施监督管理的指导意见(浙江省自然资源厅(征求意见稿)学习借鉴 以下为征求意见稿的内容,很多干活: 各市、县(市、区)自然资源主管部门: 为加强国土空间规划…...
408链表的创建和初始化
首先第一个头文件,定义结构体类型 typedef struct LNode {int data;struct LNode* next; }LNode,*LinkList; //可能作为第一次写c语言的小伙伴看不懂这一段typedef是如何定义的 //基本的解释如下所示 //typedef struct LNode LNode; //typedef struct LNode* LinkL…...
Python数据框/列表生成一列多个同样的值
例1:Python生成100个数字2 方法一: import numpy as np a np.random.randint(2,3,100) 方法二: a [2] list a * 100 #100个数字2的列表 例2:生成100个字符串棒 b 棒 list_b b * 100...

使用 MDC 实现日志链路跟踪,包教包会!
在微服务环境中,我们经常使用 Skywalking、Spring Cloud Sleut 等去实现整体请求链路的追踪,但是这个整体运维成本高,架构复杂,本次我们来使用 MDC 通过 Log 来实现一个轻量级的会话事务跟踪功能,需要的朋友可以参考一…...

【成都信息工程大学】只考程序设计!成都信息工程大学计算机考研考情分析!
成都信息工程大学(Chengdu University of Information Technology),简称“成信大”,由中国气象局和四川省人民政府共建,入选中国首批“卓越工程师教育培养计划”、“2011计划”、“中西部高校基础能力建设工程”、四川…...

将单列数据帧转换成多列数据帧
文章目录 1. 查看数据文件2. 读取数据文件得到单例数据帧3. 将单列数据帧转换成多列数据帧 在本次实战中,我们的目标是将存储在HDFS上的以逗号分隔的文本文件student.txt转换为结构化的Spark DataFrame。首先,使用spark.read.text读取文件,得…...

信息学奥赛初赛天天练-20-完善程序-vector数组参数引用传递、二分中值与二分边界应用的深度解析
PDF文档公众号回复关键字:20240605 1 2023 CSP-J 完善程序1 完善程序(单选题,每小题 3 分,共计 30 分) 原有长度为 n1,公差为1等升数列,将数列输到程序的数组时移除了一个元素,导致长度为 n 的开序数组…...

推荐系统学习 一
参考:一文看懂推荐系统:召回08:双塔模型——线上服务需要离线存物品向量、模型更新分为全量更新和增量更新_数据库全量更新和增量更新流程图-CSDN博客 一文看懂推荐系统:概要01:推荐系统的基本概念_王树森 小红书-CSD…...
分库分表详解
文章目录 分库分表概述分库分表详解分库分表的策略分库分表的注意事项常用的分库分表中间件mysql单表达到多少数据量需要分库分表数据库分库分表缺点分表要停服吗,不停服怎么做 分库分表概述 分库分表是数据库架构设计中的一种常见策略,尤其是在面对大规…...
【java前端课堂】04_类的继承
类的继承 在Java中,继承是面向对象编程的四大基本特性之一,它允许我们根据一个已有的类来定义一个新的类,这个新的类继承了原有类的特性(属性和方法),并可以添加新的特性或修改原有特性。这样,…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...