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();
	}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐