From bf7f432278aba60ee503e632ec147a6518857986 Mon Sep 17 00:00:00 2001 From: Eterlaze <1215710470@qq.com> Date: Sat, 21 Dec 2024 16:04:32 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=97=A5=E5=BF=97=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/api/aspect/LogAspect.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 IDEA/src/main/java/com/example/api/aspect/LogAspect.java diff --git a/IDEA/src/main/java/com/example/api/aspect/LogAspect.java b/IDEA/src/main/java/com/example/api/aspect/LogAspect.java new file mode 100644 index 00000000..0abdcb1b --- /dev/null +++ b/IDEA/src/main/java/com/example/api/aspect/LogAspect.java @@ -0,0 +1,86 @@ +package com.example.api.aspect; + +import com.example.api.annotation.Log; +import com.example.api.model.entity.SystemLog; +import com.example.api.service.SystemLogService; +import com.example.api.utils.IpUtil; +import com.example.api.utils.JwtTokenUtil; +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.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.time.LocalDateTime; + +/** + * LogAspect 类是一个切面(Aspect),用于记录系统日志。 + */ +@Aspect // 表明这是一个切面 +@Component // 表明这是一个 Spring 组件 +public class LogAspect { + @Autowired // 自动注入 SystemLogService + private SystemLogService logService; + + /** + * 定义切点,匹配所有标记了 @Log 注解的方法。 + */ + @Pointcut("@annotation(com.example.api.annotation.Log)") + public void pt(){} + + /** + * 环绕通知,用于在目标方法执行前后记录日志。 + * @param point 连接点 + * @return 方法执行结果 + * @throws Throwable 可能抛出的异常 + */ + @Around("pt()") + public Object Around(ProceedingJoinPoint point) throws Throwable { + // 记录开始时间 + long beginTime = System.currentTimeMillis(); + Object res = null; + try { + // 执行方法 + res = point.proceed(); + } finally { + // 计算执行时长 + long time = System.currentTimeMillis() - beginTime; + recordLog(point); + } + return res; + } + + /** + * 记录日志的方法。 + * @param point 连接点 + */ + private void recordLog(ProceedingJoinPoint point){ + // 获取当前请求对象 + ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + HttpServletRequest request = requestAttributes.getRequest(); + // 获取目标方法签名 + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + Log annotation = method.getAnnotation(Log.class); + // 封装日志对象 + SystemLog systemLog = new SystemLog(); + systemLog.setModule(annotation.module()); + systemLog.setBusinessType(annotation.type().getName()); + systemLog.setIp(IpUtil.getIpAddr(request)); + systemLog.setTime(LocalDateTime.now()); + // 获取方法的全路径 + systemLog.setMethod(signature.getDeclaringTypeName()+"."+signature.getName()); + // 获取token,并解析token来获取当前账号 + String token = request.getHeader(JwtTokenUtil.TOKEN_HEADER); + systemLog.setAccount(JwtTokenUtil.getUsername(token)); + // 持久化到数据库 + logService.record(systemLog); + } +}