spring-boot aop 增删改操作日志 实现
1.注解接口:
import com.github.wxiaoqi.security.common.constant.Constants;
import java.lang.annotation.*;
/**
* 日志注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLogOpt {
String value();
String module() default ""; //模块名称 系统管理-用户管理-列表页面
String description() default ""; //描述
Constants.LogOptEnum operationType() default Constants.LogOptEnum.UNKNOW;//操作类型
}
2.切面类
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.duiyue.common.mvc.core.APIResponse;
import com.duiyue.common.util.LogUtils;
import com.github.wxiaoqi.security.admin.annotation.SysLogOpt;
import com.github.wxiaoqi.security.admin.biz.SysLogService;
import com.github.wxiaoqi.security.api.entity.SysLog;
import com.github.wxiaoqi.security.common.constant.Constants;
import com.github.wxiaoqi.security.common.context.BaseContextHandler;
import com.github.wxiaoqi.security.common.util.RegexUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
@Slf4j
@Aspect
@Component
public class LogAspect {
/**
* 开始时间
*/
private long startTime = 0L;
@Resource
private SysLogService logService;
@Pointcut("execution(* *..rest..*.*(..)) && @annotation(com.github.wxiaoqi.security.admin.annotation.SysLogOpt)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
startTime = System.currentTimeMillis();
Object result = null;
SysLog sysLogModel = logPre(pjp);
try {
result = pjp.proceed();
} finally {
//查询类型不添加日志
if (Constants.LogOptEnum.QUERY.value() != sysLogModel.getOperationType()) {
if (logAfter(result, sysLogModel).getUserName() != null) {
sysLogModel.setCreateTime(new Date());
sysLogModel.setUpdateTime(new Date());
logService.add(sysLogModel);
}
}
}
return result;
}
private SysLog logPre(ProceedingJoinPoint pjp) throws Exception {
SysLog sysLogModel = new SysLog();
for (Method method : Class.forName(pjp.getTarget().getClass().getName()).getMethods()) {
if (method.getName().equals(pjp.getSignature().getName())) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == pjp.getArgs().length) {
//方法名称
sysLogModel.setOperation(method.getAnnotation(SysLogOpt.class).value());
//操作类型
sysLogModel.setOperationType(method.getAnnotation(SysLogOpt.class).operationType().value());
break;
}
}
}
//获取请求对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
startTime = System.currentTimeMillis();
String ip = HttpUtil.getClientIP(request);
//方法名含包名(om.github.wxiaoqi.security.admin.rest.SysLogController.queryListPage)
String classMethod = pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName();
//请求参数
String args = JSON.toJSONString(pjp.getArgs()).replaceAll(RegexUtil.getJSonValueRegex("password"), "****").replaceAll(RegexUtil.getJSonValueRegex("oldPassword"), "****");
sysLogModel.setIp(ip);
sysLogModel.setMethod(classMethod);
sysLogModel.setParams(args);
sysLogModel.setCreateTime(new Date());
sysLogModel.setCreateUser(0L);
sysLogModel.setUpdateUser(0L);
String currentUserName = "";
try {
currentUserName = BaseContextHandler.getUsername();
} catch (Exception e) {
LogUtils.error(log, "", e);
}
if (StringUtils.isNotEmpty(currentUserName)) {
sysLogModel.setUserName(currentUserName);
}
return sysLogModel;
}
private SysLog logAfter(Object result, SysLog sysLogModel) {
APIResponse response = null;
if (result != null) {
response = (APIResponse) result;
}
String currentUserName = "";
try {
currentUserName = BaseContextHandler.getUsername();
} catch (Exception e) {
LogUtils.error(log, "", e);
}
if (StringUtils.isNotEmpty(currentUserName)) {
sysLogModel.setUserName(currentUserName);
}
//返回结果
if (response != null && response.getStatus() == Constants.ResultCodeEnum.SUCCESS.value()) {
sysLogModel.setResult(1);
} else {
sysLogModel.setResult(0);
}
//执行时长(毫秒)
Long spendTime = System.currentTimeMillis() - startTime;
sysLogModel.setProcessTime(spendTime);
return sysLogModel;
}
}
3.控制层使用(方法上使用)。
@SysLogOpt(module = "活动管理", value = "添加活动", operationType = Constants.LogOptEnum.ADD)
(注:枚举类型未给出,自行修改)
spring-boot aop 增删改操作日志 实现的更多相关文章
- idea社区版+第一个spring boot项目+增删改查+yml修改端口号
参考:https://www.cnblogs.com/tanlei-sxs/p/9855071.html 中途出现问题时参考了太多 1.下载idea社区版 2.在settings -> Plug ...
- Spring Boot WebFlux 增删改查完整实战 demo
03:WebFlux Web CRUD 实践 前言 上一篇基于功能性端点去创建一个简单服务,实现了 Hello .这一篇用 Spring Boot WebFlux 的注解控制层技术创建一个 CRUD ...
- redis 与 spring整合 hash 增删改操作 list增删改操作
本人,对于以前redis的学习是非常痛苦的!近期将以前的东西捡起来.以博客的形式存储,以便于以后快速捡起来,并和广大同胞一起分享! 1):简单介绍 redis 是基于C语言开发. redis是一个ke ...
- spring boot aop 自定义注解 实现 日志检验 权限过滤
核心代码: package com.tran.demo.aspect; import java.lang.reflect.Method; import java.time.LocalDateTime; ...
- Spring Boot(二):数据库操作
本文主要讲解如何通过spring boot来访问数据库,本文会演示三种方式来访问数据库,第一种是JdbcTemplate,第二种是JPA,第三种是Mybatis.之前已经提到过,本系列会以一个博客系统 ...
- Hibernate4 拦截器(Interceptor) 实现实体类增删改的日志记录
转自:https://blog.csdn.net/he90227/article/details/44783099 开发应用程序的过程中,经常会对一些比较重要的数据修改都需要写日志.在实际工作的工程中 ...
- Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理
Spring Boot AOP之对请求的参数入参与返回结果进行拦截处理 本文链接:https://blog.csdn.net/puhaiyang/article/details/78146620 ...
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- Spring Boot AOP解析
Spring Boot AOP 面向切面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方面. AOP(Aspec ...
随机推荐
- java+selenium+testNG+Allure报表【新增截图到报表功能】
1.pom.xml配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://w ...
- selenium2.x 与 selenium3.x 最大区别
一.selenium2.x 与 selenium3.x 最大区别 (1) 从3.0版本selenium开始使用火狐浏览器完成web自动化就需要用到驱动包了. (2) 而2.0版本的selenium使用 ...
- .NET Core资料精选:架构篇
.NET 6.0 马上就要发布,高性能云原生开发框架.希望有更多的小伙伴加入大.NET阵营.这是本系列的第三篇文章:架构篇,喜欢的园友速度学起来啊. 本系列文章,主要分享一些.NET Core比较优秀 ...
- Mysql教程:(五)多表查询
多表查询 select name,student.class,student.number,maths,chinese,english from student,score where student ...
- 数组 & 对象 & 函数
数组 数组也是一个对象,不同的是对象用字符串作为属性名,而数组用数字作为索引,数组的索引从0开始 创建数组: //方式一:构造器,可以在创建数组时指定 Var arr = new Array(1,2, ...
- 浅谈springboot自动配置原理
前言 springboot自动配置关键在于@SpringBootApplication注解,启动类之所以作为项目启动的入口,也是因为该注解,下面浅谈下这个注解的作用和实现原理 @SpringBootA ...
- CAP 5.2 版本发布通告
前言 今天,我们很高兴宣布 CAP 发布 5.2 版本正式版,在这个版本中,我们主要致力于更好的优化使用体验以及支持新的 Transport,同时在该版本也进行了一些 bug 修复的工作. 自从 5. ...
- SQLServer创建约束
--创建数据库create database studentson primary( name=stu_data, filename='f:\SQL\stu_data.mdf', s ...
- [cf1305G]Kuroni and Antihype
对整个过程构造一张有向图,其中$(x,y)\in E$当且仅当$x$把$y$加入,且边权为$a_{x}$ 显然这是一棵外向树森林,并再做如下两个构造: 1.新建一个点$a_{0}=0$,将其向所有入度 ...
- [loj2978]杜老师
假设所有素数从小到大依次为$p_{1},p_{2},...,p_{k}$,我们将$x$转换为一个$k$位的二进制数,其中从低到高第$i$位为1当且仅当其$p_{i}$的幂次为奇数 不难发现以下两个性质 ...