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

AOP案例

黑马程序员JavaWeb开发教程

文章目录

  • 一、案例
    • 1.1 案例
    • 1.2 步骤
      • 1.2.1 准备
      • 1.2.2 编码

一、案例

1.1 案例

  • 将之前案例中增、删、改相关节后的操作日志记录到数据库表中。
  1. 操作日志:日志信息包含:操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值、方法执行时长
  2. 思路分析
    • 需要对所有业务中的增、删、改方法添加同一功能,使用AOP技术最为方便,@Around 环绕通知
    • 由于增、删、改方法名没有规律,可以自定义@Log 注解完成目标方法匹配

1.2 步骤

1.2.1 准备

  1. 在案例工程中引入AOP的起步依赖
<!--        AOP起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>
  1. 在数据库中新建日志数据表,并引入对应的实体类
  • 创建数据表语句
-- 操作日志表
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 编码

  1. 自定义注解@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 {
}
  1. 定义切面类,完成记录操作日志的逻辑
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;}
}
  1. 在所有增删改的方法上加上注解@Log

相关文章:

AOP案例

黑马程序员JavaWeb开发教程 文章目录 一、案例1.1 案例1.2 步骤1.2.1 准备1.2.2 编码 一、案例 1.1 案例 将之前案例中增、删、改相关节后的操作日志记录到数据库表中。 操作日志&#xff1a;日志信息包含&#xff1a;操作人、操作时间、执行方法的全类名、执行方法名、方法…...

Facebook海外户Facebook广告被暂停的原因

有很多伙伴在Facebook广告时&#xff0c;有时会遇到账号被暂停&#xff0c;并通知你违反了哪些规则&#xff0c;那么Facebook广告被暂停的原因有哪些呢&#xff1f;今天小编详细梳理了一些原因&#xff0c;可以往下看哦~ 您的Facebook广告被暂停可能有以下几个原因&#xff1a…...

网站企业需要适用于什么服务器?

对于网站企业会选择什么样的服务器呢&#xff1f; 为了保证网站能够稳定的运行需要选择高可用性和可靠性的网站服务器&#xff0c;选择具备高可用性架构的云服务器供应商&#xff0c;能够提供多可用区部署、自动故障转移和备份恢复等功能&#xff0c;保障网站在各种故障情况下的…...

winscp无法上传,删除,修改文件并提示权限不够的分析

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

Hadoop3:MapReduce之InputFormat数据输入过程整体概览(0)

一、MapReduce中数据流向 二、MapTask并行度 1、原理概览 数据块&#xff1a;Block是HDFS物理上把数据分成一块一块。数据块是HDFS存储数据单位。 数据切片&#xff1a;数据切片只是在逻辑上对输入进行分片&#xff0c;并不会在磁盘上将其切分成片进行存储。数据切片是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)…...

深度学习 - 张量的广播机制和复杂运算

张量的广播机制&#xff08;Broadcasting&#xff09;是一种处理不同形状张量进行数学运算的方式。通过广播机制&#xff0c;PyTorch可以自动扩展较小的张量&#xff0c;使其与较大的张量形状兼容&#xff0c;从而进行元素级的运算。广播机制遵循以下规则&#xff1a; 如果张量…...

【CSS】will-change 属性详解

目录 基本语法属性值常见用途will-change 如何用于优化动画效果示例&#xff1a; will-change 是一个 CSS 属性&#xff0c;用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化渲染性能&#xff0c;提前做一些准备工作&#xff0c;从而提高性能。 基本语法…...

linux安装mysql后,配置mysql,并连接navicat软件

Xshell连接登陆服务器 输入全局命令 mysql -u root -p 回车后&#xff0c;输入密码&#xff0c;不显示输入的密码 注意mysql服务状态&#xff0c;是否运行等 修改配置文件my.cnf&#xff0c;这里没找到就找my.ini&#xff0c;指定有一个是对的 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 读…...

自然资源-关于加强规划实施监督管理的指导意见(浙江省自然资源厅学习借鉴)

自然资源-关于加强规划实施监督管理的指导意见&#xff08;浙江省自然资源厅&#xff08;征求意见稿&#xff09;学习借鉴 以下为征求意见稿的内容&#xff0c;很多干活&#xff1a; 各市、县&#xff08;市、区&#xff09;自然资源主管部门&#xff1a; 为加强国土空间规划…...

408链表的创建和初始化

首先第一个头文件&#xff0c;定义结构体类型 typedef struct LNode {int data;struct LNode* next; }LNode,*LinkList; //可能作为第一次写c语言的小伙伴看不懂这一段typedef是如何定义的 //基本的解释如下所示 //typedef struct LNode LNode; //typedef struct LNode* LinkL…...

Python数据框/列表生成一列多个同样的值

例1&#xff1a;Python生成100个数字2 方法一&#xff1a; import numpy as np a np.random.randint(2,3,100) 方法二&#xff1a; a [2] list a * 100 #100个数字2的列表 例2&#xff1a;生成100个字符串棒 b 棒 list_b b * 100...

使用 MDC 实现日志链路跟踪,包教包会!

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

【成都信息工程大学】只考程序设计!成都信息工程大学计算机考研考情分析!

成都信息工程大学&#xff08;Chengdu University of Information Technology&#xff09;&#xff0c;简称“成信大”&#xff0c;由中国气象局和四川省人民政府共建&#xff0c;入选中国首批“卓越工程师教育培养计划”、“2011计划”、“中西部高校基础能力建设工程”、四川…...

将单列数据帧转换成多列数据帧

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

信息学奥赛初赛天天练-20-完善程序-vector数组参数引用传递、二分中值与二分边界应用的深度解析

PDF文档公众号回复关键字:20240605 1 2023 CSP-J 完善程序1 完善程序&#xff08;单选题&#xff0c;每小题 3 分&#xff0c;共计 30 分&#xff09; 原有长度为 n1,公差为1等升数列&#xff0c;将数列输到程序的数组时移除了一个元素&#xff0c;导致长度为 n 的开序数组…...

推荐系统学习 一

参考&#xff1a;一文看懂推荐系统&#xff1a;召回08&#xff1a;双塔模型——线上服务需要离线存物品向量、模型更新分为全量更新和增量更新_数据库全量更新和增量更新流程图-CSDN博客 一文看懂推荐系统&#xff1a;概要01&#xff1a;推荐系统的基本概念_王树森 小红书-CSD…...

分库分表详解

文章目录 分库分表概述分库分表详解分库分表的策略分库分表的注意事项常用的分库分表中间件mysql单表达到多少数据量需要分库分表数据库分库分表缺点分表要停服吗&#xff0c;不停服怎么做 分库分表概述 分库分表是数据库架构设计中的一种常见策略&#xff0c;尤其是在面对大规…...

【java前端课堂】04_类的继承

类的继承 在Java中&#xff0c;继承是面向对象编程的四大基本特性之一&#xff0c;它允许我们根据一个已有的类来定义一个新的类&#xff0c;这个新的类继承了原有类的特性&#xff08;属性和方法&#xff09;&#xff0c;并可以添加新的特性或修改原有特性。这样&#xff0c;…...

React nginx配置,一个端口代理多个项目(转发后找不到CSS,JS及图片资源问题解决)

场景&#xff1a; nginx 配置负载均衡&#xff0c;甲方只提供一个端口&#xff0c;一个域名地址 方法&#xff1a; 一个端口一个域名匹配多个应用 方法一&#xff1a; 依靠设备浏览器区分: 使用UserAgent头来识别用户的客户端, CDN监测vary头的信息&#xff0c;如果内容不一致…...

Unity协程详解

什么是协程 协程&#xff0c;即Coroutine&#xff08;协同程序&#xff09;&#xff0c;就是开启一段和主程序异步执行的逻辑处理&#xff0c;什么是异步执行&#xff0c;异步执行是指程序的执行并不是按照从上往下执行。如果我们学过c语言&#xff0c;我们应该知道&#xff0…...

【iOS】UI学习(二)

目录 前言UIViewContorllerUIViewContorller基础UIViewContorller使用 定时器和视图移动UISwitch控件UIProgressView和UISlider总结 前言 本篇博客是笔者在学习UI部分内容时的成果和遇到的一些问题&#xff0c;既是我自己的学习笔记&#xff0c;也希望对你有帮助&#xff5e; …...

React路由(React笔记之五)

本文是结合实践中和学习技术文章总结出来的笔记(个人使用),如有雷同纯属正常((✿◠‿◠)) 喜欢的话点个赞,谢谢! React路由介绍 现在前端的项目一般都是SPA单页面应用,不再是以前多个页面多套HTML代码项目了,应用内的跳转不需要刷新页面就能完成页面跳转靠的就是路由系统 R…...

调用讯飞星火API实现图像生成

目录 1. 作者介绍2. 关于理论方面的知识介绍3. 关于实验过程的介绍&#xff0c;完整实验代码&#xff0c;测试结果3.1 API获取3.2 代码解析与运行结果3.2.1 完整代码3.2.2 运行结果 3.3 界面的编写&#xff08;进阶&#xff09; 4. 问题分析5. 参考链接 1. 作者介绍 刘来顺&am…...

reduce过滤递归符合条件的数据

图片展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head><…...

Go微服务: 基于rocketmq:5.2.0搭建RocketMQ环境,以及示例参考

概述 参考最新官方文档&#xff1a;https://rocketmq.apache.org/zh/docs/quickStart/03quickstartWithDockercompose以及&#xff1a;https://rocketmq.apache.org/zh/docs/deploymentOperations/04Dashboard综合以上两个文档来搭建环境 搭建RocketMQ环境 1 ) 基于 docker-c…...

Wpf 使用 Prism 开发MyToDo应用程序

MyToDo 是使用 WPF &#xff0c;并且塔配Prism 框架进行开发的项目。项目中进行了前后端分离设计&#xff0c;客户端所有的数据均通过API接口获取。适合新手入门学习WPF以及Prism 框架使用。 首页统计以及点击导航到相关模块功能待办事项增删改查功能备忘录增删改查功能登录注册…...

vue-Dialog 自定义title样式

展示结果 vue代码 <el-dialog :title"title" :visible.sync"classifyOpen" width"500px" :showClose"false" class"aboutDialog"> <el-form :model"classifyForm" :rules"classifyRules">…...

数据库主键设计

文章目录 前言1. 自增ID&#xff08;Auto-Increment&#xff09;2. GUID (Globally Unique Identifier)3. 雪花算法&#xff08;Snowflake&#xff09;处理时钟回拨的方法1. 简单等待2. 配置时钟回拨安全窗口3. 使用不同的机器 ID 小结稳定的雪花算法实现方案示例实现1. 定义雪…...

海洋网站建设性价比高/大搜推广

1.纹理坐标 纹理坐标是纹理图像上的坐标&#xff0c;通过纹理坐标可以在纹理图像上获取纹理颜色。WebGL系统中的纹理坐标系统是二维的&#xff0c;如图所示。为了将纹理坐标和广泛使用的x、y坐标区分开来&#xff0c;WebGL使用s和t命名纹理坐标&#xff08;st坐标系统&#xff…...

网站建设费用会计科目/知乎seo排名帝搜软件

全卷积网络是语义分割的开创性工作&#xff0c;然而&#xff0c;FCN的感受野有限&#xff0c;不能有效捕捉语义分割所需要的全局上下文信息&#xff0c;因此FCN被后来的方法打败&#xff0c;比如增加不同size的滤波器来获得多尺度感受野&#xff0c;然而这势必增加参数数量。不…...

做代购的购物网站/营销存在的问题及改进

返回&#xff1a;贺老师课程教学链接 C语言及程序设计初步 【阅读程序题】 1、写出以下程序的输出结果&#xff0c;再在计算机上运行程序。对比两结果是否相同&#xff0c;以此检查自己的学习效果。2、遇到在视频中未讲的格式控制符&#xff0c;上网搜索发现其用途。&#xf…...

山东鲁为建设集团网站/关键词搜索引擎工具

openvc环境的配置 1.下载opencv:https://opencv.org/ 2.解压opencv,配置opencv程序集目录到window环境变量中 3.vs中包含目录的配置 4.vs中库目录的配置 5.vs活动解决方案配置...

做物流哪个网站货源多/seo优化神器

1、abs()求绝对值 aabs(-10) print(a) # 输出&#xff1a;10 2、all() 用来检测列表元素是否全部为空、0、False print(all([0,5,4])) #当列表所有元素都为空、False或0时&#xff0c;返回值为False&#xff0c;否则都为True print(all({1:1,2:2})) #不能测试字典&#xff0c;所…...

网站建设公司市场/免费网站制作教程

为什么80%的码农都做不了架构师&#xff1f;>>> 同步、异步&#xff1a; 指的是能否开启新的线程。同步不能开启新的线程&#xff0c;异步可以。 串行、并行&#xff1a; 指的是任务的执行方式。串行是指多个任务时&#xff0c;各个任务按顺序执行&#xff0c;完成…...