springboot中使用aop将操作日志记录到数据库

本文介绍如何在Spring Boot项目中使用AOP(面向切面编程)进行操作日志的记录。通过在pom.xml中引入spring-boot-starter-aop依赖,创建实体类AdminLog,自定义MyLog注解,实现SysLogAspect切面类,以及mapper层操作,最终在控制器中测试日志的保存。此方法能有效记录系统操作,便于后续的审计和维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.pom中引入aop依赖

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

2.创建实体类

import java.io.Serializable;

/**
 * 日志表
 * */
public class AdminLog implements Serializable {

    private static final long serialVersionUID = 7925874058046995566L;

    private String id;
    private String userId;//用户id 操作人ID
    private String userName;//用户名称 关联admin_user
    private String loginip;//登录ip
    private int type;//操作类型(0登录、1查询、2修改)
    private String url ; // 操作的url
    private String operation;//操作内容
    private String createtime;//操作时间
    private String remark;//备注
	/**生成getter和setter方法 */

3.自定义log注解

import java.lang.annotation.*;

/**
 * created by chen on 2019/8/6.
 * 配置自定义log注解类
 */
@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface MyLog {
    /** 操作事件     */
    String operation () default "";

    /** 日志类型 */
    int type ();
}

4.创建aop切面实现类

import com.***.admin.entity.AdminLog;
import com.***.admin.entity.AdminUser;
import com.***.util.UUIDUtil;
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;
import java.util.Date;

/** 系统日志:切面处理类 */
@Aspect
@Component
public class SysLogAspect {
	/**我这里是使用log4j2把一些信息打印在控制台上面,可以不写 */
    private static final Logger log = LogManager.getLogger(SysLogAspect.class);

	/**操作数据库 */
    @Autowired
    private MyLogMapper myLogMapper;

    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation(com.***.log.MyLog)")
    public void logPoinCut() {
    }

    //切面 配置通知
    @Before("logPoinCut()")         //AfterReturning
    public void saveOperation(JoinPoint joinPoint) {
        log.info("---------------接口日志记录---------------");
        //用于保存日志
        AdminLog adminLog = new AdminLog();

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();

        //获取操作--方法上的Log的值
        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);
        }

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURL = request.getRequestURL().toString();
        adminLog.setUrl(requestURL);
        // 客户端ip
        String ip = request.getRemoteAddr();
        adminLog.setLoginip(ip);
        // 操作人账号、姓名(需要提前将用户信息存到session)
        AdminUser user = (AdminUser) request.getSession().getAttribute("user");
        if(user != null) {
            String userId = user.getId();
            String userName = user.getName();
            adminLog.setUserId(userId);
            adminLog.setUserName(userName);
        }
        log.info("url="+requestURL,"ip="+ip);
       
        //调用service保存Operation实体类到数据库
        //我id使用的是UUID,不需要的可以注释掉
        String id = UUIDUtil.getUUID();
        adminLog.setId(id);
        myLogMapper.insert(adminLog);
    }
}

5.mapper层将操作添加到数据库

import com.***.admin.entity.AdminLog;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;

/**
 * created by Administrator on 2019/8/6.
 */
@Mapper
public interface MyLogMapper {
    @Insert("insert into admin_log" +
            " (id,user_id,user_name,loginip,type,url,operation,createtime,remark)" +
            " values" +
            " (#{id},#{userId},#{userName},#{loginip},#{type},#{url},#{operation},now(),#{remark})")
    void insert(AdminLog adminLog);
}

6.测试

@RestController
@RequestMapping("user")
public class UserController {

    private static final Logger log = LogManager.getLogger(UserController.class);

    @Autowired
    private UserService userService;
  
    /*测试操作日志保存到数据库*/
    /*假装登录,将用户信息存到session(方法是我之前写的懒得改,所以直接取的第一条数据)*/
    @RequestMapping("/login")
    public List<AdminUser> login(HttpServletRequest request){
        List<AdminUser> user = userService.getUser();
        AdminUser user1 = user.get(0);
        request.getSession().setAttribute("user",user1);
        return user;
    }
    /*记录日志*/
    @MyLog(operation = "查询用户信息",type = 1)
    @RequestMapping("/log")
    public List<AdminUser> insertLog(HttpServletRequest request){
        List<AdminUser> user = userService.getUser();
        return user;
    }
}

然后是控制台打印信息
在这里插入图片描述
数据库信息
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值