SpringBoot自定注解+SpringAop实现操作日志

Stella981
• 阅读 833

使用自定义注解+SpringAop实现操作日志记录,记录内容包括请求参数、请求方法、请求响应时间等的记录。

一、在pom文件中,引入依赖包和插件。

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

<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

lombok还需安装插件。我这里只是主要的包引入,还有其他的需要自行引入。

二、自定义注解

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 定义系统日志注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {

    String value() default "";

}

三、编写AOP切面类

import com.google.gson.Gson;
import com.piao.annotation.SysLog;
import com.piao.sys.sysconfig.bo.SysLogBo;
import com.piao.sys.sysconfig.service.SysLogService;
import com.power.common.util.DateTimeUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统日志切面
 */
@Aspect
@Component
@AllArgsConstructor
public class SysLogAspect {

    private final SysLogService sysLogService;

    /**
     * 这里我们使用注解的形式 当然,我们也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method 切点表达式:
     * execution(...)
     */
    @Pointcut("@annotation(com.piao.annotation.SysLog)")
    public void logPointCut() {}

    /**
     * 环绕通知 @Around , 当然也可以使用 @Before (前置通知) @After (后置通知)
     *
     * @param point
     * @return
     * @throws Throwable
     */
    @SneakyThrows
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) {
        long beginTime = System.currentTimeMillis();
        Object result = point.proceed();
        long time = System.currentTimeMillis() - beginTime;
        SysLogBo sysLog = getLog(point, time);
        sysLogService.addSysLog(sysLog);

        return result;
    }

    /**
     * 获取日志信息
     *
     * @param joinPoint
     * @param time
     */
    private SysLogBo getLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLogBo sysLogBO = new SysLogBo();
        sysLogBO.setExeuTime(time);
        sysLogBO.setCreateDate(DateTimeUtil.nowStrTime());
        SysLog sysLog = method.getAnnotation(SysLog.class);
        if (sysLog != null) {
            // 注解上的描述
            sysLogBO.setRemark(sysLog.value());
        }
        // 请求的 类名、方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLogBO.setClassName(className);
        sysLogBO.setMethodName(methodName);
        // 请求的参数
        Object[] args = joinPoint.getArgs();
        List<String> list = new ArrayList(args.length);
        for (Object o : args) {
            list.add(new Gson().toJson(o));
        }
        sysLogBO.setParams(list.toString());

        return sysLogBO;
    }

}

四、编写日志业务实体

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class SysLogBo {

    private long exeuTime;

    private String createDate;

    private String className;

    private String methodName;

    private String params;

    private String remark;

}

五、编写日志业务服务和实现

import com.baomidou.mybatisplus.extension.api.R;
import com.piao.sys.sysconfig.bo.SysLogBo;

/**
 * 系统日志服务
 */
public interface SysLogService {

    R addSysLog(SysLogBo sysLog);

}

import com.baomidou.mybatisplus.extension.api.R;
import com.piao.sys.sysconfig.bo.SysLogBo;
import com.piao.sys.sysconfig.service.SysLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * 系统日志服务实现
 */
@Slf4j
@Service
public class SysLogServiceImpl implements SysLogService {

    @Async
    @Override
    public R addSysLog(SysLogBo sysLog) {
        //这里可以编写存入数据库,es或者进行其他持久化
        log.info(sysLog.toString());
        return R.ok(sysLog);
    }

}

我这里实现类只是记录到日志里面去了,大家可以根据自己的需求去持久化记录。

六、使用自定义注解验证效果。

import com.piao.annotation.SysLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @SysLog(value = "获取一个例子")
    @GetMapping(value = "/getDemo")
    public String getDemo(){
        String str = "this is a zhirong user";
        return str;
    }

}

我们通过swagger文档来调用添加了自定义注解的接口,也可以通过浏览器调用。

SpringBoot自定注解+SpringAop实现操作日志

下面我们看控制台输出的日志,已经成功调用了日志服务,并输出了日志信息。

SpringBoot自定注解+SpringAop实现操作日志

更多阅读

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
3年前
SpringBoot自定注解+SpringAop实现操作日志
使用自定义注解SpringAop实现操作日志记录,记录内容包括请求参数、请求方法、请求响应时间等的记录。一、在pom文件中,引入依赖包和插件。<dependency<groupIdorg.springframework.boot</groupId<artifactIdspringbootsta
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这