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

