当前位置: 首页 > 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
http://www.lryc.cn/news/364506.html

相关文章:

  • Facebook海外户Facebook广告被暂停的原因
  • 网站企业需要适用于什么服务器?
  • winscp无法上传,删除,修改文件并提示权限不够的分析
  • Hadoop3:MapReduce之InputFormat数据输入过程整体概览(0)
  • 【Leetcode Python】70.爬楼梯
  • 深度学习 - 张量的广播机制和复杂运算
  • 【CSS】will-change 属性详解
  • linux安装mysql后,配置mysql,并连接navicat软件
  • 【学习笔记】Axios、Promise
  • 自然资源-关于加强规划实施监督管理的指导意见(浙江省自然资源厅学习借鉴)
  • 408链表的创建和初始化
  • Python数据框/列表生成一列多个同样的值
  • 使用 MDC 实现日志链路跟踪,包教包会!
  • 【成都信息工程大学】只考程序设计!成都信息工程大学计算机考研考情分析!
  • 将单列数据帧转换成多列数据帧
  • 信息学奥赛初赛天天练-20-完善程序-vector数组参数引用传递、二分中值与二分边界应用的深度解析
  • 推荐系统学习 一
  • 分库分表详解
  • 【java前端课堂】04_类的继承
  • React nginx配置,一个端口代理多个项目(转发后找不到CSS,JS及图片资源问题解决)
  • Unity协程详解
  • 【iOS】UI学习(二)
  • React路由(React笔记之五)
  • 调用讯飞星火API实现图像生成
  • reduce过滤递归符合条件的数据
  • Go微服务: 基于rocketmq:5.2.0搭建RocketMQ环境,以及示例参考
  • Wpf 使用 Prism 开发MyToDo应用程序
  • vue-Dialog 自定义title样式
  • 数据库主键设计
  • 小熊家务帮day13-day14 门户管理(ES搜索,Canal+MQ同步,索引同步)