@Before
-> 方法体 -> @AfterThrowing
-> @After
@After
的触发范围更广,始终是最后一个执行的通知。@AfterReturning
只在方法正常返回时触发,发生在 @After
之前。如果我们采用的是时间纬度的分表,可以创建12个表对应的12个月,如果采用实时创建的话对于创建时机可能要仔细定夺,所以还不如直接给它创建完
package com.todoitbo.baseSpringbootDasmart.annotation;
import java.lang.annotation.*;
/**
* 自定义操作日志注解
*
* @author bo
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
/**
* 功能模块
*
* @return java.lang.String
*/
String operModule() default "";
/**
* 请求类型
*
* @return java.lang.String
*/
String operType() default "";
/**
* description: describe
* @return java.lang.String
* @since 2024/11/22
*/
String describe() default "";
}
/**
* 设置操作日志切入点 记录操作日志 在注解的位置切入代码
*/
@Pointcut("@annotation(com.todoitbo.baseSpringbootDasmart.annotation.SysLog)")
public void operLogPointCut() {
}
/**
* 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行, 如果连接点抛出异常,则不会执行
*
* @param joinPoint 切入点
* @param keys 返回结果
*/
@AfterReturning(value = "operLogPointCut()", returning = "keys")
public void saveOperLog(JoinPoint joinPoint, Object keys) {
// 获取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
// 从获取RequestAttributes中获取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes
.resolveReference(RequestAttributes.REFERENCE_REQUEST);
// 获取用户信息
SysLoginInfo sysLoginInfo = LoginContextUtil.getSysLoginInfo();
SysOperationLog sysOperationLog = new SysOperationLog();
try {
// 从切面织入点处通过反射机制获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入点所在的方法
Method method = signature.getMethod();
// 获取操作
SysLog opLog = method.getAnnotation(SysLog.class);
if (opLog != null) {
sysOperationLog.setOpDescribe(opLog.describe());
sysOperationLog.setModule(opLog.operModule());
}
// 获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
// 获取请求的方法名
String methodName = method.getName();
methodName = className + "." + methodName;
sysOperationLog.setId(IdUtil.getSnowflake().nextId());
sysOperationLog.setMethod(methodName);
sysOperationLog.setRequest(JSONObject.toJSONString(joinPoint.getArgs()));
sysOperationLog.setResponse(JSONObject.toJSONString(keys));
sysOperationLog.setUrl(request.getRequestURI());
sysOperationLog.setIp(IpUtil.getIpAddr(request));
sysOperationLog.setUserId(ObjectUtil.isNotEmpty(sysLoginInfo) ? sysLoginInfo.getSysUser().getId() : 0);
sysOperationLog.setUserName(ObjectUtil.isNotEmpty(sysLoginInfo) ? sysLoginInfo.getSysUser().getUserName() : "无登录信息!");
sysOperationLogService.insertSysOperationLog(sysOperationLog);
} catch (Exception e) {
throw new BusinessException("保存操作日志失败!");
}
}
依次调用post和get方法