Springboot中 AOP实现日志信息的记录到数据库

news2024/11/25 0:41:06

1、导入相关的依赖

   <!--spring切面aop依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

注意:在application.properties文件里加这样一条配置 spring.aop.auto=true

2、创建要保存的数据信息实体类

package com.example.zheng.pojo;

import java.io.Serializable;

public class Syslog implements Serializable {
    private String id;  //我用的全宇宙唯一的子串串、也是直接用的工具类

    private 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;
    }
}

3 、编写对应的sql语句

create table syslog(
id varchar(50) not null comment '主键',
username varchar(20) not null comment '用户名',
operation varchar(100) not null comment '操作',
method varchar(50) not null comment '方法名',
createDate varchar(50) not null comment '时间',
primary key(id)

)comment='日志'

4、使用spring 的 aop 技术切到自定义注解上,所以先创建一个自定义注解类

package com.example.zheng.pojo;

import java.lang.annotation.*;

/**
 * 自定义注解类
 */
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档

public @interface  Mylog {
    String value() default "";
}

5、 创建aop切面实现类

package com.example.zheng.pojo;

import com.alibaba.druid.support.json.JSONUtils;

import com.example.zheng.Utils.CurrentTime;

import com.example.zheng.Utils.UUIDutils;
import com.example.zheng.service.SysLogService;
import org.apache.shiro.SecurityUtils;
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 javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 系统日志:切面处理类
 */
@Aspect
@Component
public class SysLogAspect {


    @Autowired
    private SysLogService sysLogService;//将数据写入数据库的操作


    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation( com.example.zheng.pojo.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);//保存获取的操作
        }

        //设置id
        String id = UUIDutils.getUUID();
        sysLog.setId(id);

        //获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        //获取请求的方法名
        String methodName = method.getName();
        sysLog.setMethod(className + "." + methodName);

        //获取时间
        String time = CurrentTime.getCurrentTime();
        sysLog.setCreateDate(time);
        //获取用户名
        //拿到当前用户的信息、我这里使用的shiro。直接从shiro中获取当前用户信息
        Customer parent  = (Customer) SecurityUtils.getSubject().getPrincipal();
        sysLog.setUsername(parent.getUsercount());


        //调用service保存SysLog实体类到数据库
        sysLogService.addLog(sysLog);
    }
}

6、在实体类中的具体应用

接下来就可以在需要监控的方法上添加 aop的自定义注解 格式为 @+自定义注解的类名 @MyLog

8、service接口

package com.example.zheng.service;

import com.example.zheng.pojo.Syslog;

public interface SysLogService {

    //写入日志
    int addLog(Syslog syslog);

}

9、接口的实现类

package com.example.zheng.service.impl;

import com.example.zheng.mapper.SysLogMapper;
import com.example.zheng.pojo.Syslog;
import com.example.zheng.service.SysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SysLogServiceImpl implements SysLogService {

    @Autowired
    SysLogMapper sysLogMapper;

    //写入日志
    @Override
    public int addLog(Syslog syslog) {
        return sysLogMapper.addLog(syslog);
    }
}

10、dao层

package com.example.zheng.mapper;


import com.example.zheng.pojo.Syslog;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper    //这个注解表示这个是mybatis的mapeper
@Repository
public interface SysLogMapper {
    //写入日志
    int addLog(Syslog syslog);
}

11、编写的mapper文件

<?xml version="1.0" encoding="UTF8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.zheng.mapper.SysLogMapper">

<insert id="addLog" parameterType="com.example.zheng.pojo.Syslog">
    insert into syslog(id,username,operation,method,createDate)
    values (#{id},#{username},#{operation},#{method},#{createDate})
</insert>


</mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/786339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

串2:云计算架构思考

开始之前&#xff0c;先给出串1&#xff1a;一文将大数据、云计算、物联网、5G&#xff08;移动网&#xff09;、人工智能等最新技术串起来_龙赤子的博客-CSDN博客 承上 事物的复杂性一般有两个方面&#xff0c;一个是本身结构的复杂&#xff0c;一个是运行机制的复杂。因为这…

如何判断某个视频是深度伪造的?

目录 一、前言 二、仔细检查面部动作 三、声音可以提供线索 四、观察视频中人物的身体姿势 五、小心无意义的词语 深造伪造危险吗&#xff1f; 一、前言 制作深度伪造视频就像在Word文档中编辑文本一样简单。换句话说&#xff0c;您可以拍下任何人的视频&#xff0c;让他…

Java 使用 Google Guava 实现接口限流

一、引入依赖 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30.0-jre</version> </dependency>二、自定义注解及限流拦截器 自定义注解&#xff1a;Limiter package com.haita…

更省更快更安全的云服务器,一站式集中管理,随时随地远程——站斧云桌面

随着全球化和数字化经济的发展&#xff0c;越来越多的企业开始海外扩张和拓展国际市场。而云服务器作为一种高效、灵活且可靠的IT基础设施方案&#xff0c;已成为出海企业不可或缺的重要工具。这里就为大家介绍云服务器在出海企业中的几个使用场景。 1.全球范围内协同办公 对…

Unity 资源与源码

Unity场景资源 Unity场景资源

USB TO TTL

什么是USB TO TTL&#xff1f; 常用的单片机&#xff0c;引出来的串口&#xff0c;如果不加其他的接口电路&#xff0c;出来的信号就是TTL电平。 如果需要看串口的打印信息&#xff0c;一般是需要接一个上位机的&#xff0c;常规的就是电脑&#xff0c;而现在的电脑一般的通信…

transformer理解

transformer的理解 Q、K、V的理解 核心是自注意力机制。即每个位置的结果为所有位置的加权平均和。为了得到每个位置的权重,需要Q*K得到。 整个多头的self-attention过程 单个encoder encoder-decoder encoder中的K和V会传到decoder中的encoder-decoder attention中。 …

Linux实训笔记~操作系统概述

1、操作系统 操作系统作为接口的示意图: 没有安装操作系统的计算机, 通常被称为裸机。 2、不同应用利于的主流操作系统 桌面操作系统 服务器操作系统 嵌入式操作系统 移动设备操作系统

postman接口测试实战讲解

目录 背景描述 创建一个GET请求 在pre-request scripts构建签名 脚本写在环境变量中 postman console的用法 Collection Runner 自动化API测试 创建接口的测试用例 选择并运行自动化接口测试 测试结果 有还不懂的同学可以找我拿演示视频喔 背景描述 有一个项目要使…

C语言实现基于Linux,epoll和多线程的WebServer服务器

代码结构&#xff1a; Server.h 头文件&#xff0c;对函数进行了声明 #pragma once #include<stdio.h> // 新建一个用于TCP监听的socket文件描述符&#xff0c;并返回 int initListenFd(unsigned short port);// 启动epoll int epollRun(int lfd);// accept建立连接 vo…

SpringCloudAlibaba微服务实战系列(五)Sentinel1.8.5+Nacos持久化

Sentinel数据持久化 前面介绍Sentinel的流控、熔断降级等功能&#xff0c;同时Sentinel应用也在面临着一个问题&#xff1a;我们在Sentinel后台管理界面中配置了一堆流控、降级规则&#xff0c;但是Sentinel一重启&#xff0c;这些规则全部消失了。那么我们就要考虑Sentinel的持…

【代码随想录day19】从中序与后序遍历序列构造二叉树

题目 思路 思路同 从前序与中序遍历序列构造二叉树&#xff0c;区别是root需要从postorder列表的尾部取。 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left l…

CSRF跨站请求伪造总结

CSRF 什么是CSRF&#xff1f; CSRF被称为跨站请求伪造&#xff0c;它利用用户已登录的身份&#xff0c;在用户毫不知情的情况下&#xff0c;以用户的名义完成非法操作。 跟跨站脚本攻击&#xff08;XSS&#xff09;相比&#xff0c;XSS利用的是用户对指定网站的信任&#xf…

JasperReport与SpringBoot整合及模板制作

0. 示例代码 示例代码地址 1. 报表介绍 1.1 为什么要使用报表? 在企业级应用开发中&#xff0c;报表生成、报表打印下载是其重要的一个环节。除了Excel报表之外&#xff0c;PDF报表也有广泛的应用场景&#xff0c;必须用户详细资料&#xff0c;用户简历等 目前世面上比较流…

数据结构(二)

目录 Trie树 并查集 堆 Trie树 作用:用来高效地存储和查找字符串集合的数据结构 基本形式: 模板代码如下: #include<iostream> using namespace std;const int N 100010;//idx代表当前用到哪个下标 //既是根节点&#xff0c;又是空节点 //cnt存储的是以当前点结尾的…

在Springboot集成Activiti工作流引擎-引入、调用,测试【基础讲解】

工作流 通过计算机对业务流程自动化执行管理 他主要解决的是使在多个参与者之间按照某种“预定义规则”自动进行传递稳定 信息或任务的过程 通俗来讲 业务上一个玩着的审批流程 比如请假&#xff0c;出差 外出采购等 工作流引擎就是来解决流程问题的 提高我们的工作效率 如果…

day43-Spring_IOC

0目录 1.2.3 1. Spring_IOC 1.1 定义&#xff1a;轻量级框架&#xff0c;java EE的春天&#xff0c;主流框架 1.2 Spring特性&#xff1a;IOC控制反转&#xff1b;AOP面相切面 1.3 组成部分&#xff1a;Spring在SSM中所起到的作用&#xff08;SpringMVC和Mybatis框架的黏…

Mybatis-Plus插入数据返回主键两种方式(注解或XML)

废话不多说&#xff0c;直接撸代码: <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace&qu…

如何在Windows上恢复已删除的文件?

大多数人在无意中删除了一些重要文件后无法恢复。这些文件被暂时删除&#xff0c;直到我们清空回收站才会消失。你可以通过右键单击回收站中的文件并选择还原选项来轻松恢复这些文件。但是&#xff0c;如果你清理回收站删除了文件怎么办&#xff1f;或者不小心使用Shift Delet…

“玩趣味游戏 学交通规则”—九彩乡未成年人教育实践活动

为进一步提高未成年人道路交通安全与文明出行意识&#xff0c;有效防范道路交通事故发生&#xff0c;2023年7月21日上午&#xff0c;在海原县民政局、海原县未成年人救助保护中心、九彩乡未成年人保护工作站的支持指导下&#xff0c;海原县知行社会工作发展中心、九彩乡红十字志…