diff --git a/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java b/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java index 991906c..7dbe196 100644 --- a/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java +++ b/yami-shop-sys/src/main/java/com/yami/shop/sys/aspect/SysLogAspect.java @@ -27,54 +27,81 @@ import org.springframework.stereotype.Component; import java.util.Date; /** + * SysLogAspect类,用于实现系统日志记录的切面功能。 + * 通过AOP(面向切面编程)的方式,拦截被特定注解标记的方法,在方法执行前后进行相关操作, + * 主要用于收集系统操作的相关信息并保存为系统日志,方便后续的审计、排查问题等操作。 + * * @author lgh */ @Aspect @Component public class SysLogAspect { - @Autowired - private SysLogService sysLogService; - private static Logger logger = LoggerFactory.getLogger(SysLogAspect.class); - @Around("@annotation(sysLog)") - public Object around(ProceedingJoinPoint joinPoint,com.yami.shop.common.annotation.SysLog sysLog) throws Throwable { - long beginTime = SystemClock.now(); - //执行方法 - Object result = joinPoint.proceed(); - //执行时长(毫秒) - long time = SystemClock.now() - beginTime; + // 自动注入SysLogService,用于将收集到的日志信息保存到数据库等存储介质中 + @Autowired + private SysLogService sysLogService; + + // 使用SLF4J的Logger来记录日志信息,方便在出现问题或者调试时输出相关的提示信息 + private static Logger logger = LoggerFactory.getLogger(SysLogAspect.class); + + /** + * Around注解表示这是一个环绕通知方法,它会在目标方法执行前后进行增强处理。 + * 这里拦截了被@SysLog注解标记的方法,在方法执行前记录开始时间,执行后计算执行时长, + * 并收集如操作描述、请求方法名、参数、IP地址、用户名等信息,封装成SysLog对象后保存到系统日志中。 + * + * @param joinPoint 连接点对象,通过它可以获取目标方法的相关信息,如方法名、参数等 + * @param sysLog 被拦截方法上标注的@SysLog注解对象,用于获取操作描述信息 + * @return 目标方法执行的结果,保证原方法的执行逻辑不受影响并能将结果正确返回给调用者 + * @throws Throwable 如果目标方法执行过程中抛出异常,会在这里继续向上抛出,保证异常处理机制正常工作 + */ + @Around("@annotation(sysLog)") + public Object around(ProceedingJoinPoint joinPoint, com.yami.shop.common.annotation.SysLog sysLog) throws Throwable { + // 获取方法执行前的时间戳(使用SystemClock.now()获取更精准的时间,可能比System.currentTimeMillis()性能更好) + long beginTime = SystemClock.now(); + + // 执行被拦截的目标方法,获取其返回结果。如果目标方法有异常抛出,会在这里直接抛出,后续代码不会执行 + Object result = joinPoint.proceed(); + + // 计算方法执行所花费的时间(单位:毫秒),通过当前时间减去方法开始执行的时间得到 + long time = SystemClock.now() - beginTime; + // 创建一个SysLog实体对象,用于封装要保存的系统日志信息 + SysLog sysLogEntity = new SysLog(); - SysLog sysLogEntity = new SysLog(); - if(sysLog != null){ - //注解上的描述 - sysLogEntity.setOperation(sysLog.value()); - } + // 如果被拦截的方法上标注的@SysLog注解不为空,则将注解中的描述信息设置为系统日志的操作描述 + if (sysLog!= null) { + // 注解上的描述,通常是对该操作的简要说明,例如“用户登录操作”等 + sysLogEntity.setOperation(sysLog.value()); + } - //请求的方法名 - String className = joinPoint.getTarget().getClass().getName(); - String methodName = joinPoint.getSignature().getName(); - sysLogEntity.setMethod(className + "." + methodName + "()"); + // 获取请求的方法名,通过连接点对象获取目标类的全限定名以及方法名,拼接成完整的方法调用表示形式 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = joinPoint.getSignature().getName(); + sysLogEntity.setMethod(className + "." + methodName + "()"); - //请求的参数 - Object[] args = joinPoint.getArgs(); - String params = Json.toJsonString(args[0]); - sysLogEntity.setParams(params); + // 获取请求的参数,通过连接点对象获取方法的参数数组,这里将参数转换为JSON字符串进行存储(方便查看参数详情), + // 目前只取了参数数组中的第一个元素进行转换,如果参数有多个可能需要更完善的处理逻辑 + Object[] args = joinPoint.getArgs(); + String params = Json.toJsonString(args[0]); + sysLogEntity.setParams(params); - //设置IP地址 - sysLogEntity.setIp(IpHelper.getIpAddr()); + // 设置IP地址,通过IpHelper工具类获取客户端的IP地址信息,并设置到系统日志实体中 + sysLogEntity.setIp(IpHelper.getIpAddr()); - //用户名 - String username = SecurityUtils.getSysUser().getUsername(); - sysLogEntity.setUsername(username); + // 获取用户名,通过SecurityUtils工具类获取当前登录系统的用户信息,再获取用户名,设置到系统日志实体中 + String username = SecurityUtils.getSysUser().getUsername(); + sysLogEntity.setUsername(username); - sysLogEntity.setTime(time); - sysLogEntity.setCreateDate(new Date()); - //保存系统日志 - sysLogService.save(sysLogEntity); + // 设置方法执行时长(单位:毫秒)到系统日志实体中 + sysLogEntity.setTime(time); + // 设置系统日志的创建日期,使用当前时间作为创建时间 + sysLogEntity.setCreateDate(new Date()); - return result; - } + // 调用SysLogService的save方法,将封装好的系统日志实体保存到数据库或者其他存储介质中,实现系统日志记录功能 + sysLogService.save(sysLogEntity); -} + // 返回目标方法执行的结果,保证原方法调用链的正常返回逻辑 + return result; + } +} \ No newline at end of file