怎么做卖衣服网站,网站优化成都哪里好,学习做网站要多久,网站建设误区文章目录 一、问题描述二、问题分析三、断掉调试四、代码展示 一、问题描述
需求#xff1a;将项目中增、删、改相关接口的操作日志记录到数据库表中。
操作日志信息包含#xff1a;
操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值、方法执行时… 文章目录 一、问题描述二、问题分析三、断掉调试四、代码展示 一、问题描述
需求将项目中增、删、改相关接口的操作日志记录到数据库表中。
操作日志信息包含
操作人、操作时间、执行方法的全类名、执行方法名、方法运行时参数、返回值、方法执行时长 所记录的日志信息包括当前接口的操作人是谁操作的什么时间点操作的以及访问的是哪个类当中的哪个方法在访问这个方法的时候传入进来的参数是什么访问这个方法最终拿到的返回值是什么以及整个接口方法的运行时长是多长时间。 二、问题分析
问题1项目当中增删改相关的方法是不是有很多
问题2我们需要针对每一个功能接口方法进行修改在每一个功能接口当中都来记录这些操作日志吗
以上两个问题的解决方案可以使用AOP解决(每一个增删改功能接口中要实现的记录操作日志的逻辑代码是相同)。 可以把这部分记录操作日志的通用的、重复性的逻辑代码抽取出来定义在一个通知方法当中我们通过AOP面向切面编程的方式在不改动原始功能的基础上来对原始的功能进行增强。目前我们所增强的功能就是来记录操作日志所以也可以使用AOP的技术来实现。使用AOP的技术来实现也是最为简单最为方便的。 问题3既然要基于AOP面向切面编程的方式来完成的功能那么我们要使用 AOP五种通知类型当中的哪种通知类型
答案环绕通知 所记录的操作日志当中包括操作人、操作时间访问的是哪个类、哪个方法、方法运行时参数、方法的返回值、方法的运行时长。 方法返回值是在原始方法执行后才能获取到的。 方法的运行时长需要原始方法运行之前记录开始时间原始方法运行之后记录结束时间。通过计算获得方法的执行耗时。 基于以上的分析我们确定要使用Around环绕通知。 问题4最后一个问题切入点表达式我们该怎么写
答案使用annotation来描述表达式 要匹配业务接口当中所有的增删改的方法而增删改方法在命名上没有共同的前缀或后缀。此时如果使用execution切入点表达式也可以但是会比较繁琐。 当遇到增删改的方法名没有规律时就可以使用 annotation切入点表达式 三、断掉调试
让我们用debug来看一下先来看看修改相关的操作 放行断点
通过debug看控制台的operateLog对面都注入成功 我们来看看数据库 最后来看看查询时的情况
最后来看看数据库 四、代码展示
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.METHOD)
public interface OperationLog {
}Data
AllArgsConstructor
NoArgsConstructor
Builder
public class OperateLog {private Long id; //主键IDprivate Long operateUser; //操作人IDprivate LocalDateTime operateTime; //操作时间private String className; //操作类名private String methodName; //操作方法名private String methodParams; //操作方法参数private String returnValue; //操作方法返回值private Long costTime; //操作耗时
}CREATE TABLE operate_log (id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT ID,operate_user bigint unsigned DEFAULT NULL COMMENT 操作人ID,operate_time datetime DEFAULT NULL COMMENT 操作时间,class_name varchar(100) DEFAULT NULL COMMENT 操作的类名,method_name varchar(100) DEFAULT NULL COMMENT 操作的方法名,method_params varchar(1000) DEFAULT NULL COMMENT 方法参数,return_value varchar(2000) DEFAULT NULL COMMENT 返回值,cost_time bigint DEFAULT NULL COMMENT 方法执行耗时, 单位:ms,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT23 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci COMMENT操作日志表Component
Aspect
Slf4j
public class OperationAspect {Autowiredprivate OperateLogMapper operateLogMapper;Around(annotation(com.sky.annotation.OperationLog))public Object log(ProceedingJoinPoint joinPoint) {try {Long operateUser BaseContext.getCurrentId();//操作人IDLocalDateTime now LocalDateTime.now();//操作时间long begin System.currentTimeMillis();//开始时间String className joinPoint.getTarget().getClass().getName();//操作类名String methodName joinPoint.getSignature().getName();//操作方法名Object[] args joinPoint.getArgs();String methodParams Arrays.toString(args);//操作方法参数Object result joinPoint.proceed();//调用原始目标方法运行long end System.currentTimeMillis();String returnValue JSONObject.toJSONString(result);//方法返回值long costTime end - begin;//操作耗时OperateLog operateLog new OperateLog(null, operateUser, now, className, methodName, methodParams, returnValue, costTime);operateLogMapper.insert(operateLog);return result;} catch (Throwable e) {throw new RuntimeException(e);}}
}