欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring如何基于aop实现操作日志功能

程序员文章站 2022-06-22 11:49:56
1. 在pom中添加所需依赖创建一个springboot工程,添加所需要的依赖,持久化用的是mybatis org.sp...

1. 在pom中添加所需依赖

创建一个springboot工程,添加所需要的依赖,持久化用的是mybatis

        <dependency>
			<groupid>org.springframework.boot</groupid>
			<artifactid>spring-boot-starter-web</artifactid>
		</dependency>
		<!--springboot aop依赖-->
		<dependency>
			<groupid>org.springframework.boot</groupid>
			<artifactid>spring-boot-starter-aop</artifactid>
		</dependency>
		<!--mybatis-->
		<dependency>
			<groupid>org.mybatis.spring.boot</groupid>
			<artifactid>mybatis-spring-boot-starter</artifactid>
			<version>2.1.3</version>
		</dependency>
		<!--mysql连接-->
		<dependency>
			<groupid>mysql</groupid>
			<artifactid>mysql-connector-java</artifactid>
			<version>8.0.19</version>
			<scope>runtime</scope>
		</dependency>
		<!--lombok-->
		<dependency>
			<groupid>org.projectlombok</groupid>
			<artifactid>lombok</artifactid>
			<optional>true</optional>
		</dependency>

2. 创建日志实体类

import lombok.data;

import java.io.serializable;

@data
public class adminlog implements serializable {

  private static final long serialversionuid = -291495801959706565l;

  private integer id; //日志记录id
  private integer userid;//操作人id
  private string username;//操作人name
  private string loginip;//登录ip
  private int type;
  private string url;
  private string operation;
  private string createtime;
  private string remark;

}

3. 自定义log注解

import java.lang.annotation.*;

/**
 * 自定义日志注解
 */
@target(elementtype.method) //注解防止位置
@retention(retentionpolicy.runtime)//运行时可见
@documented //生成文档
public @interface mylog {
  string operation() default "";

  int type();
}

4. 创建aop切面处理类

import cn.***.springaopdemo.anno.mylog;
import cn.***.springaopdemo.dao.mylogmapper;
import cn.***.springaopdemo.pojo.admin;
import cn.***.springaopdemo.pojo.adminlog;
import org.apache.logging.log4j.logmanager;
import org.apache.logging.log4j.logger;
import org.aspectj.lang.joinpoint;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.before;
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;

/**
 * 切面处理类
 */
@aspect
@component
public class syslogaspect {
  /**
   * 使用log4j2把一些信息打印在控制台上面
   */
  private static final logger log = logmanager.getlogger(syslogaspect.class);

  @autowired
  private mylogmapper mylogmapper;

  //定义切点 @pointcut
  //在注解的位置切入代码
  @pointcut("@annotation(cn.***.springaopdemo.anno.mylog)")
  public void logpointcut() {

  }

  //切面 配置为前置通知
  @before("logpointcut()")
  public void saveoperation(joinpoint joinpoint) {
    log.info("---------------接口日志记录---------------");
    //创建一个日志对象
    adminlog adminlog = new adminlog();
    //获取切面织处入点的方法
    methodsignature signature = (methodsignature) joinpoint.getsignature();
    //获取切入点所在的方法
    method method = signature.getmethod();

    //获取操作日志的属性值
    mylog mylog = method.getannotation(mylog.class);

    if (mylog != null) {

      //操作事件
      string operation = mylog.operation();
      adminlog.setoperation(operation);

      //日志类型
      int type = mylog.type();
      adminlog.settype(type);

      log.info("operation=" + operation + ",type=" + type);
    }
    //获取url
    httpservletrequest request = ((servletrequestattributes) requestcontextholder.getrequestattributes()).getrequest();
    string requesturl = request.getrequesturi().tostring();
    adminlog.seturl(requesturl);

    //获取客户端ip
    string ip = request.getremoteaddr();
    adminlog.setloginip(ip);

    //获取操作人账号、姓名(需要提前将用户信息保存到session)
    admin admin = (admin) request.getsession().getattribute("admin");
    if (admin != null) {
      integer id = admin.getid();
      string name = admin.getname();
      adminlog.setuserid(id);
      adminlog.setusername(name);
    }

    log.info("url=" + requesturl + ",ip=" + ip);

    //调用service保存operation实体类到数据库
    //可以在这设置id,因为是测试,这里就使用的是数据库的自增id
    mylogmapper.insertlog(adminlog);

  }

}

5. mapper层把日志数据存储到mysql数据库中

mapper接口

import cn.***.springaopdemo.pojo.adminlog;
import java.util.list;
public interface mylogmapper {
  void insertlog(adminlog adminlog);
}

mapper.xml文件

<?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="cn.***.springaopdemo.dao.mylogmapper">

  <insert id="insertlog" parametertype="cn.***.springaopdemo.pojo.adminlog">
    insert into admin_log (user_id,user_name,loginip,type,url,operation,createtime,remark)
    values (#{userid},#{username},#{loginip},#{type},#{url},#{operation},now(),#{remark})
  </insert>
</mapper>

6. 测试

先直接登录用户,因为是测试,直接从数据库中获取后登录,把admin存储到session中

import cn.***.springaopdemo.pojo.admin;
import cn.***.springaopdemo.service.iadminservice;
import org.apache.logging.log4j.logmanager;
import org.apache.logging.log4j.logger;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

import javax.servlet.http.httpservletrequest;
import java.util.list;

@restcontroller
@requestmapping("/admin")
public class admincontroller {
  private static final logger log = logmanager.getlogger(admincontroller.class);
   //中间service层可以省略,直接通过mapper接口操作数据即可
  @autowired
  private iadminservice adminservice;

  @requestmapping("/login")
  public admin login(httpservletrequest request) {
    list<admin> adminlist = adminservice.findalladmin();
    admin admin = adminlist.get(0);
    request.getsession().setattribute("admin",admin );
    return admin;
  }

}

在浏览器中输入localhost:8080/admin/login,可以看到登录的admin
Spring如何基于aop实现操作日志功能

进行插入和查询操作,插入数据直接通过后台提供

import cn.***.springaopdemo.anno.mylog;
import cn.***.springaopdemo.pojo.type;
import cn.***.springaopdemo.service.itypeservice;
import org.apache.logging.log4j.logmanager;
import org.apache.logging.log4j.logger;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

import java.util.arraylist;
import java.util.list;

@restcontroller
@requestmapping("/type")
public class typecontroller {
  private static final logger log = logmanager.getlogger(typecontroller.class);

  @autowired
  private itypeservice typeservice;


  @mylog(operation = "增加书籍类型", type = 2)
  @requestmapping("/add")
  public void inserttype() {
    list<type> typelist = new arraylist<>();
    type type = new type();
    type.setname("自然科学");
    typelist.add(type);
    typeservice.addtypelist(typelist);
    log.info("添加书籍类型" + type.getname());
  }

  @mylog(operation = "查询所有书籍类型", type = 1)
  @requestmapping("/findall")
  public list<type> findalltype() {
    list<type> typelist = typeservice.findalltype();
    log.info("查询所有书籍类型");
    return typelist;
  }
}

在浏览器中输入localhost:8080/type/add,后台日志打印记录

Spring如何基于aop实现操作日志功能

再输入查询请求localhost:8080/type/findall,获得查询出的分类

Spring如何基于aop实现操作日志功能

查看数据库是否添加成功

Spring如何基于aop实现操作日志功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。