使用SpringBoot AOP记录操作日志和异常日志

这篇具有很好参考价值的文章主要介绍了使用SpringBoot AOP记录操作日志和异常日志。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用SpringBoot AOP记录操作日志和异常日志

平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能;我们在操作某些功

能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发

生的异常进行统计,从而改进我们的项目,要是能做个功能专门来记录操作日志和异常日志那就好了。

当然我们肯定有方法来做这件事情,而且也不会很难,我们可以在需要的方法中增加记录日志的代码,和在每个方

法中增加记录异常的代码,最终把记录的日志存到数据库中。听起来好像很容易,但是我们做起来会发现,做这项

工作很繁琐,而且都是在做一些重复性工作,还增加大量冗余代码,这种方式记录日志肯定是不可行的。

我们以前学过Spring 三大特性,IOC(控制反转),DI(依赖注入),AOP(面向切面),那其中AOP的主要功能

就是将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来。今天我们就来用

springBoot Aop 来做日志记录,好了,废话说了一大堆还是上货吧。

1、创建日志记录表、异常日志表,表结构如下

操作日志表OperationLog

CREATE TABLE `OperationLog` (
  `oper_id` varchar(64) DEFAULT NULL COMMENT '主键id',
  `oper_modul` varchar(64) DEFAULT NULL COMMENT '功能模块',
  `oper_type` varchar(64) DEFAULT NULL COMMENT '操作类型',
  `oper_desc` varchar(500) DEFAULT NULL COMMENT '操作描述',
  `oper_requ_param` text COMMENT '请求参数',
  `oper_resp_param` text COMMENT '返回参数',
  `oper_user_id` varchar(64) DEFAULT NULL COMMENT '操作员ID',
  `oper_user_name` varchar(64) DEFAULT NULL COMMENT '操作员名称',
  `oper_method` varchar(255) DEFAULT NULL COMMENT '操作方法',
  `oper_uri` varchar(255) DEFAULT NULL COMMENT '请求URI',
  `oper_ip` varchar(64) DEFAULT NULL COMMENT '请求ID',
  `oper_create_time` datetime DEFAULT NULL COMMENT '操作时间',
  `oper_ver` varchar(64) DEFAULT NULL COMMENT '操作版本号',
  PRIMARY KEY (`oper_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

异常日志表ExceptionLog

CREATE TABLE `ExceptionLog` (
  `exp_id` varchar(64) NOT NULL DEFAULT "" COMMENT '主键id',
  `exp_requ_param` text COMMENT '请求参数',
  `exp_name` varchar(255) COMMENT '异常名称',
  `exp_message` text COMMENT '异常信息',
  `oper_user_id` varchar(64) DEFAULT NULL COMMENT '操作员ID',
  `oper_user_name` varchar(64) DEFAULT NULL COMMENT '操作员名称',
  `oper_method` varchar(255) DEFAULT NULL COMMENT '操作方法',
  `oper_uri` varchar(255) DEFAULT NULL COMMENT '请求URI',
  `oper_ip` varchar(64) DEFAULT NULL COMMENT '请求ID',
  `oper_create_time` datetime DEFAULT NULL COMMENT '操作时间',
  `oper_ver` varchar(64) DEFAULT NULL COMMENT '操作版本号',
  PRIMARY KEY (`exp_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

2、添加Maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/>
    </parent>

    <groupId>com.aop.log</groupId>
    <artifactId>spring-boot-aop-log</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-aop-log</name>
    <description>spring-boot-aop-log</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- mybatis-plus依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>

        <!-- mysql依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、创建实体类

ExceptionLog实体

package com.aop.log.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

/**
 * @author zhangshixing
 * @date 2021年11月05日 10:04
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("ExceptionLog")
public class ExceptionLog {

    // 主键id
    @TableId(value = "exp_id", type = IdType.ASSIGN_UUID)
    private String expId;
    // 请求参数
    private String expRequParam;
    // 异常名称
    private String expName;
    // 异常信息
    private String expMessage;
    // 操作员ID
    private String operUserId;
    // 操作员名称
    private String operUserName;
    // 操作方法
    private String operMethod;
    // 请求URI
    private String operUri;
    // 请求ID
    private String operIp;
    // 操作时间
    private Date operCreateTime;
    // 操作版本号
    private String operVer;
}

OperationLog实体

package com.aop.log.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;

/**
 * @author zhangshixing
 * @date 2021年11月05日 9:52
 */

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("OperationLog")
public class OperationLog implements Serializable {

    // 主键id
    @TableId(value = "oper_id", type = IdType.ASSIGN_UUID)
    private String operId;
    // 功能模块
    private String operModul;
    // 操作类型
    private String operType;
    // 操作描述
    private String operDesc;
    // 请求参数
    private String operRequParam;
    // 返回参数
    private String operRespParam;
    // 操作员ID
    private String operUserId;
    // 操作员名称
    private String operUserName;
    // 操作方法
    private String operMethod;
    // 请求URI
    private String operUri;
    // 请求ID
    private String operIp;
    // 操作时间
    private Date operCreateTime;
    // 操作版本号
    private String operVer;
}

OrderInfo订单实体类

package com.aop.log.entity;

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

/**
 * @author zhangshixing
 * @date 2021年11月05日 10:33
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderInfo {

    /**
     * 这里只是为了测试所以只添加了两个参数
     */
    // 订单编号
    private String orderid;
    // 订单金额
    private int price;

}

RespBean公共返回对象

package com.aop.log.entity;

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

/**
 * @author zhangshixing
 * @date 2021年11月05日 10:31
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RespBean {

    private long code;
    private String message;
    private Object obj;

    public static RespBean success(String message) {

        return new RespBean(200, message, null);
    }

    public static RespBean success(String message, Object obj) {

        return new RespBean(200, message, obj);
    }

    public static RespBean error(String message) {

        return new RespBean(500, message, null);
    }

    public static RespBean error(String message, Object obj) {

        return new RespBean(500, message, obj);
    }
}

4、创建Mapper

OperationLogMapper

package com.aop.log.mapper;

import com.aop.log.entity.OperationLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface OperationLogMapper extends BaseMapper<OperationLog> {

}

ExceptionLogMapper

package com.aop.log.mapper;

import com.aop.log.entity.ExceptionLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface ExceptionLogMapper extends BaseMapper<ExceptionLog> {

}

5、创建service

OperationLogService

package com.aop.log.service;

import com.aop.log.entity.OperationLog;
import com.baomidou.mybatisplus.extension.service.IService;

public interface OperationLogService extends IService<OperationLog> {
}

ExceptionLogService

package com.aop.log.service;

import com.aop.log.entity.ExceptionLog;
import com.baomidou.mybatisplus.extension.service.IService;

public interface ExceptionLogService extends IService<ExceptionLog> {

}

OperationLogServiceImpl

package com.aop.log.service.impl;

import com.aop.log.entity.OperationLog;
import com.aop.log.mapper.OperationLogMapper;
import com.aop.log.service.OperationLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * @author zhangshixing
 * @date 2021年11月05日 10:10
 */
@Service
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLog>
        implements OperationLogService {
}

ExceptionLogServiceImpl

package com.aop.log.service.impl;

import com.aop.log.entity.ExceptionLog;
import com.aop.log.mapper.ExceptionLogMapper;
import com.aop.log.service.ExceptionLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/**
 * @author zhangshixing
 * @date 2021年11月05日 10:10
 */
@Service
public class ExceptionLogServiceImpl extends ServiceImpl<ExceptionLogMapper, ExceptionLog>
        implements ExceptionLogService {
}

6、创建操作日志注解类OperLog

package com.aop.log.annotation;

import java.lang.annotation.*;

/**
 * @author zhangshixing
 * @date 2021年11月05日 9:43
 * 自定义操作日志注解
 */
//注解放置的目标位置,METHOD是可注解在方法级别上
@Target(ElementType.METHOD)
//注解在哪个阶段执行
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperLog {
    // 操作模块
    String operModul() default "";

    // 操作类型
    String operType() default "";

    // 操作说明
    String operDesc() default "";
}
package com.aop.log.annotation;

public class OprLogConst {

    public static final String ADD = "add";
    public static final String INSERET = "insert";
    public static final String UPDATE = "update";
    public static final String DELETE = "delete";
}

7、创建切面类记录操作日志

package com.aop.log.aop;

import com.alibaba.fastjson.JSON;
import com.aop.log.annotation.OperLog;
import com.aop.log.entity.ExceptionLog;
import com.aop.log.entity.OperationLog;
import com.aop.log.service.ExceptionLogService;
import com.aop.log.service.OperationLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author zhangshixing
 * @date 2021年11月05日 9:46
 * 切面处理类,操作日志异常日志记录处理
 */
@Aspect
@Component
public class OperLogAspect {

    /**
     * 操作版本号
     * 项目启动时从命令行传入,例如:java -jar xxx.war --version=201902
     */
    @Value("${version}")
    private String operVer;

    @Autowired
    private OperationLogService operationLogService;

    @Autowired
    private ExceptionLogService exceptionLogService;

    /**
     * 设置操作日志切入点 记录操作日志 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.aop.log.annotation.OperLog)")
    public void operLogPoinCut() {
    }

    /**
     * 设置操作异常切入点记录异常日志 扫描所有controller包下操作
     */
    @Pointcut("execution(* com.aop.log.controller..*.*(..))")
    public void operExceptionLogPoinCut() {
    }

    /**
     * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
     *
     * @param joinPoint 切入点
     * @param keys      返回结果
     */
    @AfterReturning(value = "operLogPoinCut()", returning = "keys")
    public void saveOperLog(JoinPoint joinPoint, Object keys) {
        // 获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes
                .resolveReference(RequestAttributes.REFERENCE_REQUEST);
        // 创建OperationLog对象
        OperationLog operlog = new OperationLog();
        try {
            // 主键ID
            String uuid = UUID.randomUUID().toString();
            System.out.println("saveOperLog:" + uuid);
            operlog.setOperId(uuid);
            // 从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 获取切入点所在的方法
            Method method = signature.getMethod();
            // 获取操作
            OperLog opLog = method.getAnnotation(OperLog.class);
            if (opLog != null) {
                String operModul = opLog.operModul();
                String operType = opLog.operType();
                String operDesc = opLog.operDesc();
                // 操作模块
                operlog.setOperModul(operModul);
                // 操作类型
                operlog.setOperType(operType);
                // 操作描述
                operlog.setOperDesc(operDesc);
            }
            // 获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            // 获取请求的方法名
            String methodName = method.getName();
            methodName = className + "." + methodName;
            // 请求方法
            operlog.setOperMethod(methodName);
            // 请求的参数
            Map<String, String> rtnMap = converMap(request.getParameterMap());
            // 将参数所在的数组转换成json
            String params = JSON.toJSONString(rtnMap);
            // 请求参数
            operlog.setOperRequParam(params);
            // 返回结果
            operlog.setOperRespParam(JSON.toJSONString(keys));
            // 请求用户ID
            // operlog.setOperUserId(UserShiroUtil.getCurrentUserLoginName());
            // 这里写一个固定的用户ID
            operlog.setOperUserId("100293784");
            // 请求用户名称
            // operlog.setOperUserName(UserShiroUtil.getCurrentUserName());
            // // 这里写一个固定的用户名
            operlog.setOperUserName("yiyiyi");
            // 请求IP
            // operlog.setOperIp(IPUtil.getRemortIP(request));
            // 这里写一个固定的IP
            operlog.setOperIp("127.0.0.1");
            // 请求URI
            operlog.setOperUri(request.getRequestURI());
            // 创建时间
            operlog.setOperCreateTime(new Date());
            // 操作版本
            operlog.setOperVer(operVer);
            // 将数据插入到数据库
            operationLogService.save(operlog);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行
     *
     * @param joinPoint 切入点
     * @param e         异常信息
     */
    @AfterThrowing(pointcut = "operExceptionLogPoinCut()", throwing = "e")
    public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
        // 获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes
                .resolveReference(RequestAttributes.REFERENCE_REQUEST);
        ExceptionLog excepLog = new ExceptionLog();
        try {
            // 从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 获取切入点所在的方法
            Method method = signature.getMethod();
            String uuid = UUID.randomUUID().toString();
            System.out.println("saveExceptionLog:" + uuid);
            excepLog.setExpId(uuid);
            // 获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            // 获取请求的方法名
            String methodName = method.getName();
            methodName = className + "." + methodName;
            // 请求的参数
            Map<String, String> rtnMap = converMap(request.getParameterMap());
            // 将参数所在的数组转换成json
            String params = JSON.toJSONString(rtnMap);
            // 请求参数
            excepLog.setExpRequParam(params);
            // 请求方法名
            excepLog.setOperMethod(methodName);
            // 异常名称
            excepLog.setExpName(e.getClass().getName());
            // 异常信息
            excepLog.setExpMessage(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
            // 操作员ID
            // excepLog.setOperUserName(UserShiroUtil.getCurrentUserName());
            excepLog.setOperUserId("100293784");
            // 操作员名称
            excepLog.setOperUserName("yiyiyi");
            // 操作URI
            excepLog.setOperUri(request.getRequestURI());
            // 操作员IP
            // excepLog.setOperIp(IPUtil.getRemortIP(request));
            excepLog.setOperIp("127.0.0.1");
            // 操作版本号
            excepLog.setOperVer(operVer);
            // 发生异常时间
            excepLog.setOperCreateTime(new Date());
            exceptionLogService.save(excepLog);
        } catch (Exception e2) {
            e2.printStackTrace();
        }

    }

    /**
     * 转换request 请求参数
     *
     * @param paramMap request获取的参数数组
     */
    public Map<String, String> converMap(Map<String, String[]> paramMap) {
        Map<String, String> rtnMap = new HashMap<String, String>();
        for (String key : paramMap.keySet()) {
            rtnMap.put(key, paramMap.get(key)[0]);
        }
        return rtnMap;
    }

    /**
     * 转换异常信息为字符串
     *
     * @param exceptionName    异常名称
     * @param exceptionMessage 异常信息
     * @param elements         堆栈信息
     */
    public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
        StringBuffer strbuff = new StringBuffer();
        for (StackTraceElement stet : elements) {
            strbuff.append(stet + "\n");
        }
        String message = exceptionName + ":" + exceptionMessage + "\n\t" + strbuff.toString();
        return message;
    }
}

8、在Controller层方法添加@OperLog注解

package com.aop.log.controller;

import com.aop.log.annotation.OperLog;
import com.aop.log.annotation.OprLogConst;
import com.aop.log.entity.OrderInfo;
import com.aop.log.entity.RespBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author zhangshixing
 * @date 2021年11月05日 10:25
 */
@Controller
public class OrderController {
    /**
     * 新增订单信息
     */
    @RequestMapping(value = "addOrderInfo")
    @ResponseBody
    @OperLog(operModul = "销售管理-订单新增", operType = OprLogConst.ADD, operDesc = "订单新增功能")
    public RespBean addOrderInfo(OrderInfo orderInfo) {
        if (orderInfo.getPrice() < 0) {
            System.out.println(1 / 0);
            return RespBean.error("提交失败!!!");
        } else if (orderInfo.getPrice() < 30) {
            return RespBean.success("提交成功!!!");
        } else {
            return RespBean.error("提交失败!!!");
        }
    }
}

9、启动类和配置文件

version = 2.1.1
server.port = 9000
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/log?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username = root
spring.datasource.password = root
package com.aop.log;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootAopLogApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootAopLogApplication.class, args);
	}

}

10、操作日志、异常日志查询功能

10.1 记录操作日志

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

10.2 记录异常日志

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

使用SpringBoot AOP记录操作日志和异常日志,spring boot,spring boot

11、execution 表达式

学习Spring中的aop组装切面时遇到的execution表达式,下面是execution表达式的详解。

切入点表达式:

整个表达式可以分为五个部分:

1、execution(): 表达式主体。

2、第一个*号:方法返回类型, *号表示所有的类型。

3、包名:表示需要拦截的包名。

4、第二个*号:表示类名,*号表示所有的类。

5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面( )里面表示方法的参数,两个句点表示任

何参数。

表达式语法:

execution(* 包名.*.*(..))

规范写法:execution(* com.baizhi.service.UserServiceImpl.*(..))

这个表达式是重点 ,是最通用的,表示执行接口下的所有接口方法。

execution表达式举例:

书写接口实现方法:UserServiceImpl

方法类型:

add(); query(); add(String name); add(User user); add(String name,Integer age);

execution(* service.UserServiceImpl.add(..))        //执行add()方法
execution(* service.UserServiceImpl.add(String))    //执行add(String name)方法
execution(* service.UserServiceImpl.add(com.baizhi.entity.User))   //执行add(User user)方法
execution(* service.UserServiceImpl.add(String , Integer))    //执行add(String name,Interger age)方法

execution表达式的一般用法:

execution(* service.UserServiceImpl.*(java.util.List))
返回值:任意
包:com.baizhi.service
类:UserServiceImpl
方法:任意
参数:必须是List集合
execution(* service.UserServiceImpl.add*(..))  重点
返回值:任意
包:com.baizhi.service
类:UserServiceImpl
方法:以add关键字开头的方法
参数:任意
execution(* service.UserServiceImpl.*.*(..))  重点
返回值:任意
包:com.baizhi.service
类:当前包下的所有类
方法:所有类中的所有方法
参数:任意
execution(* service..*.*(..))  重点
返回值:任意
包:service包以及它下面所有子包
类:所有包中的所有类
方法:所有类中的所有方法
参数:任意
execution(* *(..))   重点,不建议这样写,栈溢出

注意:要尽可能精准的切入。文章来源地址https://www.toymoban.com/news/detail-766349.html

到了这里,关于使用SpringBoot AOP记录操作日志和异常日志的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Boot入门(23):记录接口日志再也不难!用AOP和自定义注解给Spring Boot加上日志拦截器!

            在上两期中,我们着重介绍了如何集成使用 Logback 与 log4j2 日志框架的使用,今天我们讲解的主题依旧跟日志有关,不过不是使用何种开源框架,而是自己动手造。         Spring的核心之一AOP;AOP翻译过来叫面向切面编程, 核心就是这个切面. 切面表示从业务逻辑中

    2024年02月11日
    浏览(44)
  • Java使用Aop实现用户操作日志记录(新手入门)

    导入打印日志,aop,hutool,的依赖,Hutool是一个Java工具包,里面封装了大量的常用工具类,到时候咱们就通过这个工具包中有一个工具类可以用来获取客户端IP地址。 自定义操作类型枚举类 因为基本是增删改查四个方法 自定义用来记录用户操作日志的注解 写一个方法加上我

    2024年02月06日
    浏览(34)
  • Spring Boot 如何使用 JUL 进行日志记录

    在 Spring Boot 中,我们可以使用多种日志框架进行日志记录。其中,JUL (Java Util Logging) 是 Java 平台自带的日志框架,它提供了简单的 API 和配置,可以轻松地进行日志记录。本文将介绍如何在 Spring Boot 中使用 JUL 进行日志记录,并提供示例代码。 默认情况下,Spring Boot 使用 L

    2024年02月10日
    浏览(39)
  • AOP案例-记录日志操作

    目录 案例 操作日志 思路分析 步骤 准备 编码 将案例中的增删改接口的操作日志记录到数据表中 操作日志 日志信息包括:操作人、操作时间、执行方法的全类名、执行方法名、方法运行时的参数、返回值、犯法运行时长。 思路分析 需要对于所有业务类中的增删改查方法统

    2024年02月09日
    浏览(31)
  • 【Spring Boot】通过AOP拦截Spring Boot日志并将其存入数据库

    在软件开发中,常常需要记录系统运行时的日志。日志记录有助于排查系统问题、优化系统性能、监控操作行为等。本文将介绍如何使用Spring Boot和AOP技术实现拦截系统日志并保存到数据库中的功能。 本文将通过以下步骤实现拦截系统日志并保存到数据库中的功能: 配置数据

    2024年02月10日
    浏览(35)
  • Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志

    今天主要说说如何通过自定义注解的方式,在 Spring Boot 中来实现 AOP 切面统一打印出入参日志。小伙伴们可以收藏一波。 废话不多说,进入正题! 在看看实现方法之前,我们先看下切面日志输出效果咋样: 从上图中可以看到,每个对于每个请求,开始与结束一目了然,并且

    2024年02月08日
    浏览(37)
  • 使用SpringBoot记录用户操作日志

    在工作中我们可能会遇到一个需求,就是记录用户的操作信息,接下来使用spring的aop特性实现这一需求 一、首先引入我们必要的一些依赖 二、自定义一个注解,用于标注需要监控的方法 三、在数据库中创建一张表,用来保存用户的操作日志 字段可以有  用户名  用户操作

    2024年02月06日
    浏览(37)
  • Spring Boot入门(23):基于AOP实现自定义注解拦截接口日志并保存入库 | 超级详细,建议收藏

            在上两期中,我们着重介绍了如何集成使用 Logback 与 log4j2 日志框架的使用,今天我们讲解的主题依旧跟日志有关,不过不是使用何种开源框架,而是自己动手造。         Spring的核心之一AOP;AOP翻译过来叫面向切面编程, 核心就是这个切面. 切面表示从业务逻辑中

    2024年02月11日
    浏览(35)
  • springboot 统一异常处理 + 日志记录

          在项目的开发中,在某些情况下,比如非业务的操作,日志记录,权限认证和异常处理等。我们需要对客户端发出的请求进行拦截,常用的API拦截方式有Fliter,Interceptor,ControllerAdvice以及Aspect。先简单介绍一下不同的拦截方式。 可以获得Http原始的请求和响应信息,

    2023年04月17日
    浏览(31)
  • SpringBoot小项目——简单的小区物业后台管理系统 & 认证鉴权 用户-角色模型 & AOP切面日志 & 全局异常【源码】

    基于SpringBoot的简单的小区物业后台管理系统,主要功能有报修的处理,楼宇信息和房屋信息的管理,业主信息的管理【核心】,以及数据统计分析模块Echarts绘图;此外采用用户-角色权限模型,结合自定义注解实现简单的权限管理功能,采用aop切面实现日志的存储,全局异常

    2024年02月06日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包