SpringBoot使用在控制层切面注解配置的方式将日志存储在mysql
创始人
2024-03-31 05:56:47
0

🍅程序员小王的博客:程序员小王的博客
🍅CSDN地址:程序员小王java
🍅 欢迎点赞 👍 收藏 ⭐留言 📝
🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕
🍅java自学的学习路线:java自学的学习路线

一、前言

我们写完一个项目,运维时,如果出现了bug,我们需要查看控制台的日志,但是那个日志无关方法太多,查找不是很方便,还有就是一个项目上线之后,我们需要记录谁操作了那些功能,以防出现矛盾知道是谁点了这个功能造成的问题,由谁来负责,为了解决这两个问题,我在SpringBoot项目中使用了对控制层切面+注解的方法来实现将日志存储在数据库里面

二、实现详细源码

1、相关依赖

  • springboot项目的依赖需要,还需要一个aop切面的依赖,mybatis的依赖
    org.springframework.bootspring-boot-starter-parent2.2.5.RELEASE org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-aop     

2、配置文件

在application.properties文件里加这样一条配置

server.port: 8080
spring.aop.auto=true

3、我们首先需要准备mysql表

DROP TABLE IF EXISTS `syslog`;
CREATE TABLE `syslog`  (`id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键',`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',`operation` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作',`method` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '方法名',`createDate` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '日志' ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

4、创建数据库表之后就需要写实体类了

package com.sgsg.verification.entity;
/*** @author 王恒杰* @date 2022/10/25 14:54* @Description:*/
import java.io.Serializable;
public class Syslog implements Serializable {private String id;  //我用的UUITprivate String username; //用户名private String operation; //操作private String method; //方法名private String createDate; //操作时间,这里可以使用Date来实现。我写的有个工具类。用的String接收public String getId() {return id;}public void setId(String id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getOperation() {return operation;}public void setOperation(String operation) {this.operation = operation;}public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}public String getCreateDate() {return createDate;}public void setCreateDate(String createDate) {this.createDate = createDate;}
}
  • 这里如果用lombok的话,只需要一个@Data注解
@Data
public class Syslog implements Serializable {private String id;  //我用的全宇宙唯一的子串串、也是直接用的工具类private String username; //用户名private String operation; //操作private String method; //方法名private String createDate; //操作时间,这里可以使用Date来实现。我写的有个工具类。用的String接收}

5、先写dao层和mapper层

(1)dao层

/*** @author 王恒杰* @date 2022/10/25 14:59* @Description:*/
@Mapper
public interface SysLogMapper {/*** 写入日志* @param syslog* @return*/int addLog(Syslog syslog);
}

(2)mapper层



insert into syslog(id, username, operation, method, createDate)values (#{id}, #{username}, #{operation}, #{method}, #{createDate})

6、写业务层

  • 接口层
import com.sgsg.verification.entity.Syslog;/*** @author 王恒杰* @date 2022/10/25 14:58* @Description:*/
public interface SysLogService {//写入日志int addLog(Syslog syslog);
}
  • 实现类
/*** @author 王恒杰* @date 2022/10/25 14:58* @Description:*/
@Service
public class SysLogServiceImpl implements SysLogService {@Autowiredpublic SysLogMapper sysLogMapper;//写入日志@Overridepublic int addLog(Syslog syslog) {return sysLogMapper.addLog(syslog);}}

7、切面核心方法

package com.sgsg.verification.aspect;/*** @author 王恒杰* @date 2022/10/25 14:57* @Description:*/import com.auth0.jwt.interfaces.Claim;
import com.sgsg.verification.dao.UserDao;
import com.sgsg.verification.entity.Result;
import com.sgsg.verification.entity.Syslog;
import com.sgsg.verification.entity.UserInfoEntity;
import com.sgsg.verification.log.Mylog;
import com.sgsg.verification.service.SysLogService;
import com.sgsg.verification.service.UserService;
import com.sgsg.verification.utils.JwtUtil;
import com.sgsg.verification.utils.UserInfoUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;/*** 系统日志:切面处理类*/
@Aspect
@Component
public class SysLogAspect {@Autowiredprivate SysLogService sysLogService;//将数据写入数据库的操作@Autowiredprivate UserDao userDao;@Autowiredprivate JwtUtil jwtUtil;//定义切点 @Pointcut//在注解的位置切入代码@Pointcut("@annotation(com.sgsg.verification.log.Mylog ))")public void logPoinCut() {}//切面 配置通知@AfterReturning("logPoinCut()")public void saveSysLog(JoinPoint joinPoint) {System.out.println("切面。。。。。");//保存日志Syslog sysLog = new Syslog();//从切面织入点处通过反射机制获取织入点处的方法MethodSignature signature = (MethodSignature) joinPoint.getSignature();//获取切入点所在的方法Method method = signature.getMethod();//获取操作Mylog myLog = method.getAnnotation(Mylog.class);if (myLog != null) {String value = myLog.value();sysLog.setOperation(value);//保存获取的操作}//设置idString id = UUID.randomUUID().toString();sysLog.setId(id);//获取请求的类名String className = joinPoint.getTarget().getClass().getName();//获取请求的方法名String methodName = method.getName();sysLog.setMethod(className + "." + methodName);SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");sysLog.setCreateDate(simpleDateFormat.format(new Date()));//获取用户名//拿到当前用户的信息、我这里使用的Token。直接从Token中获取当前用户信息ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();assert attributes != null;HttpServletRequest request = attributes.getRequest();// 从 http 请求头中取出 tokenString token = request.getHeader("authorization");// 解析token并获取token中的用户信息Map claims = jwtUtil.verity(token);Claim userId = claims.get("userId");//获取用户UserInfoEntity user = userDao.getInfoById(userId.asInt());sysLog.setUsername(user.getCname());//调用service保存SysLog实体类到数据库sysLogService.addLog(sysLog);}
}

8、我们自己定义注解类

package com.sgsg.verification.log;
/*** @author 王恒杰* @date 2022/10/25 14:56* @Description: 自定义注解类*/
import java.lang.annotation.*;
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档public @interface  Mylog {String value() default "";
}

9、在控制层使用我们自定义的注解

package com.sgsg.verification.controller;import com.sgsg.verification.entity.Result;
import com.sgsg.verification.log.Mylog;
import com.sgsg.verification.service.EnumService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author 王恒杰* @date 2022/10/6 12:30* @Description:*/
@Slf4j
@RestController
@RequestMapping("/enums")
public class EnumController {@Autowiredprivate EnumService enumService;@Mylog(value = "获取枚举")@GetMapping("/selectAll")public Result selectAll() {return enumService.selectAll();}
}

10、启动项目之后我们的日志就存储在数据库里面了

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...