springboot 自定义注解记录接口访问日志表
·
Advice:通知,某个连接点所采用的处理逻辑,也就是向连接点注入的代码, AOP在特定的切入点上执行的增强处理。
@Before:标识前置增强方法,相当于BeforeAdvice;
@Around:环绕增强,相当于MethodInterceptor;
@After:final增强,抛出异常和正常退出后都会执行;
@AfterReturning:后置增强,正常退出时执行,相当于AfterReturningAdvice;
@AfterThrowing:后置增强,抛出异常时执行,相当于ThrowsAdvice。
JointPoint:连接点,程序运行中的某个阶段点,比如方法的调用、异常的抛出等。
Object[] getArgs:返回目标方法的参数;
Signature getSignature:返回目标方法的签名;
Object getTarget:返回被织入增强处理的目标对象;
Object getThis:返回AOP框架为目标对象生成的代理对象。
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pig.common.log.annotation;
import java.lang.annotation.*;
/**
* 系统任务注解:用于标记需要记录操作任务的方法
*
* @author lengleng
* @date 2025/05/31
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysTask {
/**
* 描述
* @return {String}
*/
String value() default "";
/**
* spel 表达式
* @return 日志描述
*/
String expression() default "";
}
/*
* Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.pig4cloud.pig.common.log.aspect;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pig.common.core.util.SpringContextHolder;
import com.pig4cloud.pig.common.log.annotation.SysTask;
import com.pig4cloud.pig.common.log.event.SysTaskEvent;
import com.pig4cloud.pig.common.log.event.SysTaskEventSource;
import com.pig4cloud.pig.common.log.util.LogTypeEnum;
import com.pig4cloud.pig.common.log.util.SysLogUtils;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.expression.EvaluationContext;
/**
* 系统任务切面类,通过Spring AOP实现操作任务的异步记录
*
* @author lengleng
* @date 2025/05/31
*/
@Aspect
@Slf4j
@RequiredArgsConstructor
public class SysTaskAspect {
/**
* 环绕通知方法,用于处理系统任务记录
* @param point 连接点对象
* @param sysTask 系统任务注解
* @return 目标方法执行结果
* @throws Throwable 目标方法执行可能抛出的异常
@Around("@annotation(sysTask)")
@SneakyThrows
public Object around(ProceedingJoinPoint point, com.pig4cloud.pig.common.log.annotation.SysTask sysTask) {
String strClassName = point.getTarget().getClass().getName();
String strMethodName = point.getSignature().getName();
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
String value = sysTask.value();
SysTaskEventSource logVo = SysLogUtils.getSysTask();
logVo.setTitle(value);
// 获取请求body参数
if (StrUtil.isBlank(logVo.getParams())) {
logVo.setBody(point.getArgs());
}
// 发送异步任务事件
Long startTime = System.currentTimeMillis();
logVo.setTitle(value+"[开始执行]");
Object obj;
try {
obj = point.proceed();
}
catch (Exception e) {
logVo.setLogType(LogTypeEnum.ERROR.getType());
logVo.setException(e.getMessage());
throw e;
}
finally {
Long endTime = System.currentTimeMillis();
logVo.setTime(endTime - startTime);
SpringContextHolder.publishEvent(new SysTaskEvent(logVo));
}
return obj;
}
*/
/**
* 定义切面
* - 此处代表com.example.demo.module.controller包下的所有接口都会被统计
@Pointcut("@annotation(com.pig4cloud.pig.common.log.annotation.SysTask)")
// @Pointcut("execution(* cn.agile.platform.core.web.controller..*.*(..))")
public void log() {
log.info("loglog=loglog");
} */
/**
* 在接口原有的方法执行前,将会首先执行此处的代码
*/
@Before("@annotation(sysTask)")
public void doBefore(JoinPoint point,com.pig4cloud.pig.common.log.annotation.SysTask sysTask) {
MethodSignature signature = (MethodSignature)point.getSignature();
SysTask annotation = signature.getMethod().getAnnotation(SysTask.class);
log.info("在接口原有的方法执行前");
String strClassName = point.getTarget().getClass().getName();
String strMethodName = point.getSignature().getName();
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
String value = sysTask.value();
SysTaskEventSource logVo = SysLogUtils.getSysTask();
logVo.setTitle(value);
// 获取请求body参数
if (StrUtil.isBlank(logVo.getParams())) {
logVo.setBody(point.getArgs());
}
// 发送异步任务事件
Long startTime = System.currentTimeMillis();
logVo.setTitle(value+"[开始执行]");
Long endTime = System.currentTimeMillis();
logVo.setTime(endTime - startTime);
SpringContextHolder.publishEvent(new SysTaskEvent(logVo));
}
/**
* 只有正常返回才会执行此方法
* 如果程序执行失败,则不执行此方法
*/
@AfterReturning(returning = "returnVal", pointcut = "@annotation(sysTask)")
@SneakyThrows
public void doAfterReturning(JoinPoint point, Object returnVal,com.pig4cloud.pig.common.log.annotation.SysTask sysTask) {
log.info("只有正常返回才会执行此方法");
String strClassName = point.getTarget().getClass().getName();
String strMethodName = point.getSignature().getName();
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
String value = sysTask.value();
SysTaskEventSource logVo = SysLogUtils.getSysTask();
logVo.setTitle(value);
// 获取请求body参数
if (StrUtil.isBlank(logVo.getParams())) {
logVo.setBody(point.getArgs());
}
// 发送异步任务事件
Long startTime = System.currentTimeMillis();
logVo.setTitle(value+"[结束执行]");
Long endTime = System.currentTimeMillis();
logVo.setTime(endTime - startTime);
SpringContextHolder.publishEvent(new SysTaskEvent(logVo));
}
/**
* 当接口报错时执行此方法
*/
@AfterThrowing(pointcut = "@annotation(sysTask)")
public void doAfterThrowing(JoinPoint point,com.pig4cloud.pig.common.log.annotation.SysTask sysTask) {
log.info("当接口报错时执行此方法");
String strClassName = point.getTarget().getClass().getName();
String strMethodName = point.getSignature().getName();
log.debug("[类名]:{},[方法]:{}", strClassName, strMethodName);
String value = sysTask.value();
SysTaskEventSource logVo = SysLogUtils.getSysTask();
logVo.setTitle(value);
// 获取请求body参数
if (StrUtil.isBlank(logVo.getParams())) {
logVo.setBody(point.getArgs());
}
// 发送异步任务事件
Long startTime = System.currentTimeMillis();
logVo.setTitle(value+"[异常执行]");
Long endTime = System.currentTimeMillis();
logVo.setTime(endTime - startTime);
SpringContextHolder.publishEvent(new SysTaskEvent(logVo));
}
/**
* 在接口原有的方法执行后,都会执行此处的代码(final)
@After("@annotation(sysTask)")
public void doAfter(JoinPoint joinPoint,com.pig4cloud.pig.common.log.annotation.SysTask sysTask) {
log.info("在接口原有的方法执行后 ");
}*/
}
/**
* 导出角色数据到Excel表格
* @return 角色数据列表
*/
@ResponseExcel
@GetMapping("/export")
@SysTask("导出角色EXCEL数据")
@HasPermission("sys_role_export")
public List<RoleExcelVO> exportRoles() {
return sysRoleService.listRoles();
}
更多推荐
所有评论(0)