SpringBoot-AOP记录操作日志
package com.meeno.inner.oa.extend.operaterecord.aop;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.meeno.inner.oa.common.utils.AopUtils;
import com.meeno.inner.oa.extend.operaterecord.enums.OperateRecordTypeEnum;
import com.meeno.inner.oa.extend.operaterecord.repository.OperateRecordRepository;
import com.meeno.inner.oa.extend.operaterecord.service.OperateRecordService;
import com.meeno.inner.oa.extend.operaterecord.service.model.OperateRecordModel;
import com.meeno.inner.oa.extend.project.module.controller.form.ModuleModel;
import com.meeno.inner.oa.extend.project.module.entity.Module;
import com.meeno.inner.oa.extend.project.module.enums.ModuleTypeEnum;
import com.meenoframework.common.filter.ThreadLocalClient;
import lombok.NoArgsConstructor;
import lombok.extern.java.Log;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
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.stereotype.Component;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
/**
* @description: 切面类
* @author: Wzq
* @create: 2020-03-30 11:20
*/
@Aspect
@Component
@Log
public class ModuleAspect {
@Autowired
private OperateRecordService operateRecordService;
@Pointcut("execution(public * com.meeno.inner.oa.extend.project.module.service.ModuleService.*(..))")
public void cutPoint(){}
/**
* AfterReturning遇到异常不执行
* @param joinPoint
* @param retrunObj 方法返回值
*/
@AfterReturning(returning="retrunObj",pointcut = "cutPoint()")
public void before(JoinPoint joinPoint,Object retrunObj){
//获取方法名称
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
log.info("aop->MethodName:"+method.getName());
//方法中的值
Object[] args = joinPoint.getArgs();
/*Object target = joinPoint.getTarget();
Object aThis = joinPoint.getThis();
String classType = joinPoint.getTarget().getClass().getName();*/
//方法名称
String methodName = joinPoint.getSignature().getName();
MethodNameEnum methodNameEnum = MethodNameEnum.get(methodName);
HashMap<String, Object> fieldsMap = AopUtils.getFieldsName(method, args);
//获取操作记录的Model
List<OperateRecordModel> operationRecordList = null;
if(methodNameEnum != null){
operationRecordList = this.getOperationRecord(methodNameEnum, fieldsMap,retrunObj);
}
this.operateRecordService.addAll(operationRecordList);
}
public List<OperateRecordModel> getOperationRecord(MethodNameEnum methodNameEnum, HashMap<String, Object> fieldsMap,Object retrunObj){
//操作记录Model
List<OperateRecordModel> recordModelList = Lists.newArrayList();
Long loginUserId = ThreadLocalClient.get().getId();
//操作日志类型
OperateRecordTypeEnum type = OperateRecordTypeEnum.MODULE;
//模块
Module module = null;
//操作日志内容
StringBuffer content = new StringBuffer();
ModuleModel model = null;
OperateRecordModel recordModel = null;
switch (methodNameEnum){
case ADD:
content.append("创建了->");
String moduleTypeStr = null;
model = (ModuleModel) fieldsMap.get("model");
//项目id
Long projectId = model.getProjectId();
//获取模块层级
this.moduleModelLevelToString(model,content);
//获取功能点数组字符串
moduleTypeStr = model.getModuleTypeStr();
//判断是否是多个type
if(moduleTypeStr != null && !moduleTypeStr.isEmpty()){
//生成多条记录
JSONArray jsonArray = JSONArray.parseArray(moduleTypeStr);
if(jsonArray != null && !jsonArray.isEmpty()){
for (int i = 0; i < jsonArray.size(); i++) {
Integer moduleTypeCode = jsonArray.getInteger(i);
ModuleTypeEnum typeEnum = ModuleTypeEnum.getModuleTypeEnum(moduleTypeCode);
switch (typeEnum){
case WEB:
content.append(" 类型:web");
break;
case IOS:
content.append(" 类型:ios");
break;
case ANDROID:
content.append(" 类型:android");
break;
case SERVER:
content.append(" 类型:server");
break;
}
//每个type创建一条操作记录
OperateRecordModel tempRecordModel = new OperateRecordModel();
tempRecordModel.setProjectId(projectId);
tempRecordModel.setUserId(loginUserId);
tempRecordModel.setContent(content.toString());
tempRecordModel.setType(type);
//加入到集合中
recordModelList.add(tempRecordModel);
}
}
}else{
//生成一条记录
recordModel = new OperateRecordModel();
recordModel.setProjectId(projectId);
recordModel.setUserId(loginUserId);
recordModel.setContent(content.toString());
recordModel.setType(type);
//加入到集合中
recordModelList.add(recordModel);
}
break;
case EDIT:
content.append("编辑了->");
//方法中的参数
model = (ModuleModel) fieldsMap.get("model");
//返回的对象
module = (Module) retrunObj;
//获取模块层级
this.moduleModelLevelToString(model,content);
content.append(" 预计投入修改为: " + model.getPredictInput());
//生成一条记录
recordModel = new OperateRecordModel();
recordModel.setProjectId(module.getProjectId());
recordModel.setUserId(loginUserId);
recordModel.setContent(content.toString());
recordModel.setType(type);
//加入到集合中
recordModelList.add(recordModel);
break;
case DELETE:
content.append("删除了->");
//返回的对象
module = (Module) retrunObj;
//获取模块层级
this.moduleLevelToString(module,content);
//生成一条记录
recordModel = new OperateRecordModel();
recordModel.setProjectId(module.getProjectId());
recordModel.setUserId(loginUserId);
recordModel.setContent(content.toString());
recordModel.setType(type);
//加入到集合中
recordModelList.add(recordModel);
break;
case EDIT_STATUS:
content.append("修改模块状态->");
//返回的对象
module = (Module) retrunObj;
//获取模块层级
this.moduleLevelToString(module,content);
//获取模块的状态
this.moduleStatusToString(module,content);
//生成一条记录
recordModel = new OperateRecordModel();
recordModel.setProjectId(module.getProjectId());
recordModel.setUserId(loginUserId);
recordModel.setContent(content.toString());
recordModel.setType(type);
//加入到集合中
recordModelList.add(recordModel);
break;
case EDIT_REAL_INPUT:
content.append("修改模块实际投入->");
//返回的对象
module = (Module) retrunObj;
//获取模块层级
this.moduleLevelToString(module,content);
content.append(" 修改实际投入为: " + module.getRealInput());
//生成一条记录
recordModel = new OperateRecordModel();
recordModel.setProjectId(module.getProjectId());
recordModel.setUserId(loginUserId);
recordModel.setContent(content.toString());
recordModel.setType(type);
//加入到集合中
recordModelList.add(recordModel);
break;
case EDIT_PREDICT_INPUT:
content.append("修改模块预计投入->");
//返回的对象
module = (Module) retrunObj;
//获取模块层级
this.moduleLevelToString(module,content);
content.append(" 修改预计投入为: " + module.getRealInput());
//生成一条记录
recordModel = new OperateRecordModel();
recordModel.setProjectId(module.getProjectId());
recordModel.setUserId(loginUserId);
recordModel.setContent(content.toString());
recordModel.setType(type);
//加入到集合中
recordModelList.add(recordModel);
break;
/*case SET_WEIGHT:
break;*/
default:
break;
}
return recordModelList;
}
/**
* 修改模块的状态ToString
* @param module
* @param content
*/
private void moduleStatusToString(Module module,StringBuffer content){
if(module != null){
switch (module.getStatus()){
case NOT_INITIATED:
//未开始
content.append(" 修改状态为:未开始");
break;
case PROCESSING:
//进行中
content.append(" 修改状态为:进行中");
break;
case OVER:
//结束
content.append(" 修改状态为:结束");
break;
}
}
}
/**
* 模块ModelToString
* @param model
* @param content
*/
private void moduleLevelToString(Module model,StringBuffer content){
if(model != null){
switch (model.getLevel()){
case one:
//一级模块
content.append("一级模块名称:" + model.getName());
break;
case two:
//二级模块
content.append("二级模块名称:" + model.getName());
break;
case three:
//三级模块
content.append("功能点名称:" + model.getName());
break;
}
}
}
/**
* 模块ModelLevelToString
* @param model
* @param content
*/
private void moduleModelLevelToString(ModuleModel model,StringBuffer content){
if(model != null){
switch (model.getLevel()){
case one:
//一级模块
content.append("一级模块名称:" + model.getModuleName());
break;
case two:
//二级模块
content.append("二级模块名称:" + model.getModuleName());
break;
case three:
//三级模块
content.append("功能点名称:" + model.getModuleName());
break;
}
}
}
@NoArgsConstructor
private enum MethodNameEnum{
ADD("add"),
EDIT("edit"),
DELETE("delete"),
EDIT_STATUS("editStatus"),
EDIT_REAL_INPUT("editRealInput"),
EDIT_PREDICT_INPUT("editPredictInput"),
SET_WEIGHT("setWeight")
;
private String methodName;
MethodNameEnum(String methodName) {
this.methodName = methodName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public static MethodNameEnum get(String methodName){
MethodNameEnum[] values = MethodNameEnum.values();
for (MethodNameEnum value : values) {
if (value.methodName.equals(methodName)) {
return value;
}
}
return null;
}
}
}
SpringBoot-AOP记录操作日志的更多相关文章
- 使用SpringBoot AOP 记录操作日志、异常日志
平时我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能:我们在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因我们都要到服务器去查询日志才能找到,而且也不能对发 ...
- Spring aop 记录操作日志 Aspect
前几天做系统日志记录的功能,一个操作调一次记录方法,每次还得去收集参数等等,太尼玛烦了.在程序员的世界里,当你的一个功能重复出现多次,就应该想想肯定有更简单的实现方法.于是果断搜索各种资料,终于搞定了 ...
- spring-boot-route(十七)使用aop记录操作日志
在上一章内容中--使用logback管理日志,我们详细讲述了如何将日志生成文件进行存储.但是在实际开发中,使用文件存储日志用来快速查询问题并不是最方便的,一个优秀系统除了日志文件还需要将操作日志进行持 ...
- springmvc集成aop记录操作日志
首先说明一下,这篇文章只做了记录日志相关事宜 具体springmvc如何集成配置aop对cotroller进行拦截,请看作者的另一篇文章 http://www.cnblogs.com/guokai87 ...
- Spring aop 记录操作日志 Aspect 自定义注解
时间过的真快,转眼就一年了,没想到随手写的笔记会被这么多人浏览,不想误人子弟,于是整理了一个优化版,在这里感谢智斌哥提供的建议和帮助,话不多说,进入正题 所需jar包 :spring4.3相关联以及a ...
- 用AOP记录操作日志,并写进数据库。
先用AOP注解 1 package com.vlandc.oss.apigate.log.aspect; import java.util.Map; import java.util.Optional ...
- Springboot AOP写操作日志 GET POST
pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- [编码实践]SpringBoot实战:利用Spring AOP实现操作日志审计管理
设计原则和思路: 元注解方式结合AOP,灵活记录操作日志 能够记录详细错误日志为运营以及审计提供支持 日志记录尽可能减少性能影响 操作描述参数支持动态获取,其他参数自动记录. 1.定义日志记录元注解, ...
- Spring Boot中使用AOP记录请求日志
这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...
- Spring Boot AOP 简易操作日志管理
AOP (Aspect Oriented Programming) 面向切面编程. 业务有核心业务和边缘业务. 比如用户管理,菜单管理,权限管理,这些都属于核心业务. 比如日志管理,操作记录管理,这些 ...
随机推荐
- STM32中的GPIO笔记
1.GPIO是STM32可控制的引脚,STM32的GPIO被分成很多组,每组有16个引脚.每个GPIO端口包含:2个32位配置寄存器(CRL.CRH),2个32位数据寄存器(IDR.ODR),1个32 ...
- QT从入门到入土(二)——对象模型(对象树)和窗口坐标体系
摘要 我们使用的标准 C++,其设计的对象模型虽然已经提供了非常高效的 RTTI 支持,但是在某些方面还是不够灵活.比如在 GUI 编程方面,既需要高效的运行效率也需要强大的灵活性,诸如删除某窗口时可 ...
- [NOI2009] 诗人小G [题解]
诗人小G 题目大意 给出 \(n\) 个长度不超过 \(30\) 的句子,要求你对其进行排版. 对于每一行,有一个规定的行标准长度 \(L\) ,每一行的不协调度等于该行的实际长度与行标准长度差的绝对 ...
- "Shortest" pair of paths[题解]
"Shortest" pair of paths 题目大意 给出 \(n\) 个点,\(m\) 条边,除第一个点和最后一个点外,其他所有的点都只能被经过一次,要求找到两条从第一个点 ...
- python 按行查找文本文件,找出答案,并提示置顶答案
1.整理好答案文件为文本文件:不能有空行:每个题干前有数字做为题号:每个题答案第一个字符为字母,答案占一行import time import time import sys import os im ...
- C语言:异或
异或运算符"∧"也称XOR运算符.它的规则是若参加运算的两个二进位同号,则结果为0(假):异号则为1(真).即 0∧0=0,0∧1=1, 1^0=1,1∧1=0. 相同为0,不相同 ...
- win10 删除WPS提示存在wpsupdate.exe进程
这个进程在:WIN10 任务管理器 的"详细列表"查找可能有1-2个类似的,全部关闭才能删除
- 【动画消消乐】HTML+CSS 自定义加载动画:怦然心跳 066
前言 Hello!小伙伴! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 自我介绍 ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简介:因C语言结识编程,随后转入计 ...
- 《手把手教你》系列技巧篇(十一)-java+ selenium自动化测试-元素定位大法之By tag name(详细教程)
1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...
- python编写DDoS攻击脚本
python编写DDoS攻击脚本 一.什么是DDoS攻击 DDoS攻击就是分布式的拒绝服务攻击,DDoS攻击手段是在传统的DoS攻击基础之上产生的一类攻击方式.单一的DoS攻击一般是采用一对一方式的, ...