通过自定义spring aspect配合着注解的方式实现记录系统操作日志,代码侵入性低
1.定义module注解,代表模块
package com.yc.platform.admin.web.common.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 系统模块注解 * * @author zhya */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface SystemModule { /** * 系统模块,取自SystemModuleAndOperationConstant * @return */ String module() default ""; }
2.定义operation注解,代表操作
package com.yc.platform.admin.web.common.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 系统操作日志注解 * * @author zhya */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SystemOperation { /** * 操作类型,取自SystemModuleAndOperationConstant * @return */ String operation() default ""; /** * 操作的功能 * @return */ String function() default ""; }
3.定义spring切面,并设置切点为operation注解,获取关键信息并记录日志
package com.yc.platform.admin.web.common.aspect; import com.yc.platform.admin.web.common.annotation.SystemModule; import com.yc.platform.admin.web.common.annotation.SystemOperation; import com.yc.platform.admin.web.common.controller.BaseController; import com.yc.platform.admin.web.security.model.AuthUser; import com.yc.platform.system.api.entity.Sys_log.SystemOperationLog; import com.yc.platform.system.api.service.Sys_log.ISystemOperationLogService; import org.apache.commons.lang3.ArrayUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; /** * 记录系统操作日志切面 * * @author zhya */ @Aspect @Component public class RecordSystemOperationLogAspect extends BaseController { private static final Logger log = LoggerFactory.getLogger(RecordSystemOperationLogAspect.class); @Autowired private ISystemOperationLogService systemOperationLogService; /** * 设置切点为SystemOperation注解 * * @param joinPoint * @param recordSystemOperation * @return * @throws Throwable */ @Around(value = "@annotation(recordSystemOperation)") public Object log(ProceedingJoinPoint joinPoint, SystemOperation recordSystemOperation) throws Throwable { Object object = joinPoint.proceed(); Object[] args = joinPoint.getArgs(); if (ArrayUtils.isEmpty(args)) { log.error("参数错误,无法获取登录用户"); return object; } SystemModule systemModule = joinPoint.getTarget().getClass().getAnnotation(SystemModule.class); if (systemModule == null) { log.error("参数错误,无法获取系统模块,请在类定义上添加SystemModule注解"); return object; } Object obj = args[args.length - 1]; if (obj == null || !(obj instanceof HttpServletRequest)) { log.error("参数错误,请设置HttpServletRequest为方法的最后一个参数"); return object; } HttpServletRequest request = (HttpServletRequest) obj; AuthUser authUser; if (request == null || (authUser = this.getUserDetail(request)) == null) { log.error("参数错误或者用户未登录,无法获取登录用户信息,请确认登录"); return object; } log.info("record operation log : " + this.getLoginUserName(request) + " " + systemModule.module() + " " + recordSystemOperation.operation() + " " + recordSystemOperation.function()); SystemOperationLog systemOperationLog = new SystemOperationLog(); systemOperationLog.setOperatorId(authUser.getId()); systemOperationLog.setOperator(authUser.getName()); systemOperationLog.setModule(systemModule.module()); systemOperationLog.setOperationType(recordSystemOperation.operation()); systemOperationLog.setFunction(recordSystemOperation.function()); systemOperationLogService.addLog(systemOperationLog); return object; } }
4.用法
类定义上面添加module注解,表明所属模块
方法定义上添加operation,表明具体操作