通過自定義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,表明具體操作