通过自定义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,表明具体操作