Java—AOP案例-记录操作日志

发布时间:2023年12月29日

简介:上一篇文章“JAVA语言—AOP基础”已经详细的介绍了AOP的各个功能接口,已经使用步骤,这篇文章就是基于此来做的一个小案例。案例的功能是记录登录的用户对于数据库表的相关信息进行增、删、查、改的操作记录下来,并且存储到数据库中

目录

1、需求分析

2、操作步骤

2.1 引入起步依赖

2.2 创建表结构,引入实体类

2.3 自定义注解@MyLog

2.4 创建切面类

3、总结


1、需求分析

操作日志:

  • 记录登录用户的操作日志并且存储到服务器数据库中。
  • 日志信息包含:操作人、操作时间、执行方法的全类名、执行方法名、方法运行时的参数、返回值、方法执行时长。

思路分析:

  • 需要对所有业务类中的增、删、查、改 方法添加统一功能,使用AOP技术最为方便。
  • 由于增、删、查、改的方法名没有规律,可以通过注解@annotation和自定义注解完成目标方法匹配。

2、操作步骤

  • 准备:
    • 在案例中引入AOP的起步依赖
    • 导入准备好的数据库表结构,并引入对应的实体类?
  • 编码:
    • 自定义注解 @Log
    • 定义切面类,完成记录操作日志的逻辑

2.1 引入起步依赖

图2.1-1 添加依赖

2.2 创建表结构,引入实体类

  • 创建日志表结构(代码如下)
-- 操作日志表
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.tliaswebmanagement.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class OperateLog {
    private Integer id;  //ID
    private Integer operateUser; //操作人ID
    private LocalDateTime operateTime; //操作时间
    private String className; //操作类名
    private String methodName; //操作方法名
    private String methodParams; //操作方法参数
    private String returnValue; //操作方法返回值
    private Long costTime; //操作耗时
}

2.3 自定义注解@MyLog

因为采用@Annotation注解来实现定义切面类,所以需要提前创建自定义注解(代码如下)。

package com.itheima.tliaswebmanagement.aop;

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 MyLog {
}

上面的代码,首先是在根目录下创建一个anno包,在这个包里面创建一个MyLog注解。

2.4 创建切面类

创建AOP切面类,用以在用户对于数据库表的相关信息进行增、删、查、改的操作记录下来,并且存储到数据库中。

package com.itheima.tliaswebmanagement.aop;

import com.alibaba.fastjson.JSONObject;
import com.itheima.tliaswebmanagement.mapper.OperateLogMapper;
import com.itheima.tliaswebmanagement.pojo.OperateLog;
import com.itheima.tliaswebmanagement.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
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 java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Component
@Aspect
public class LogAspect {

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.itheima.tliaswebmanagement.aop.MyLog)")
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {

        log.info("around ... before ... ");

        //操作人ID - 当前登录员ID
        String jwt = httpServletRequest.getHeader("token");
        Claims claims = JwtUtils.parseJWT(jwt);
        Integer operateUser = (Integer) claims.get("id");

        //操作时间
        LocalDateTime operateTime = LocalDateTime.now();

        //操作类名
        String className = joinPoint.getTarget().getClass().getName();

        //操作方法名
        String methodName = joinPoint.getSignature().getName();

        //操作方法参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

        //原始方法运行前
        long begin = System.currentTimeMillis();

        //调用原始目标方法运行
        Object result = joinPoint.proceed();

        //原始方法运行后
        long end = System.currentTimeMillis();

        //方法返回值
        String returnValue = JSONObject.toJSONString(result);

        //操作耗时
        Long costTime = end - begin;

        //记录操作日志
        log.info("around ... after ... ");
        OperateLog operateLog = new OperateLog(null, operateUser, operateTime, className, methodName, methodParams, returnValue, costTime);
        operateLogMapper.insert(operateLog);
        log.info("AOP 操作日志: {}", operateLog);
        return result;
    }
}

因在代码中已经将相应代码的功能作用做出了注释,就不在做多余说明。

3、总结

以上就是关于AOP案例-记录操作日志的小案例分享,希望大家能给个点赞支持。

文章来源:https://blog.csdn.net/Wang_ning__/article/details/135265594
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。