具体代码
package com.example.test05.demo.config;
import com.example.test05.demo.model.UserDO;
import com.example.test05.demo.tool.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* @author DBC
* @date 2023/1/12 11:20
* @network dbc655.top
*/
@Aspect
@Component
@Slf4j
public class LogAspectHandler {
/*** 定义一个切面,拦截com.example.test05.demo.controller包和子包下的所有方法 */
@Pointcut("execution(* com.example.test05.demo.controller..*.*(..))")
public void pointcut() {
}
/**
* 前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)
* @param joinPoint
*/
@Before("pointcut()")
public void testBefore(JoinPoint joinPoint) {
log.info("[testBefore方法]:进入!");
Signature signature = joinPoint.getSignature();
String methodName = signature.getName();
String declaringTypeName = signature.getDeclaringTypeName();
log.info("[testBefore方法]:包名为:{},方法名为:{}", declaringTypeName, methodName);
// 也可以用来记录一些信息,比如获取请求的url
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//获取URL
String requestURL = request.getRequestURL().toString();
log.info("[testBefore方法]:请求的url地址为:{}",requestURL);
}
/**
* 后通知(After (finally) advice):当某连接点退出的时候执行的通知(一定执行)
* @param joinPoint
*/
@After("pointcut()")
public void testAfter(JoinPoint joinPoint) {
log.info("[testAfter方法]:进入");
Signature signature = joinPoint.getSignature();
String name = signature.getName();
log.info("[testAfter方法]:{}执行完成", name);
}
/**
* 返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回
* @param joinPoint
* @param result
*/
@AfterReturning(value = "pointcut()", returning = "result")
public void testAfterReturning(JoinPoint joinPoint, Object result) {
log.info("[testAfterReturning方法]:,返回参数为:{}", result);
JsonData jsonData = (JsonData) result;
UserDO userDO = (UserDO) jsonData.getData();
userDO.setName("[testAfterReturning方法]:dbc升级版");
userDO.setTime(new Date());
log.info("[testAfterReturning方法]:编辑后的返回值为:{}", userDO);
}
/**
* 抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。 (它和返回后通知总是只执行一个)
* @param joinPoint
* @param ex
*/
@AfterThrowing(value = "pointcut()", throwing = "ex")
public void testAfterThrowing(JoinPoint joinPoint, Throwable ex) {
log.info("[testAfterThrowing方法]:方法进入");
Signature signature = joinPoint.getSignature();
String name = signature.getName();
log.info("[testAfterThrowing方法]:{}执行出错,异常为:{}", name,ex.getMessage());
}
}
简单测试一下
@RequestMapping("/testJson")
public JsonData testJson(int error) {
if (error==1){
int i = 1 / 0;
}
UserDO userPO = new UserDO();
userPO.setName("dbc");
return JsonData.buildSuccess(userPO);
} 控制台输出
2023-01-12 15:05:35 JRebel: Reconfiguring bean 'logAspectHandler' [com.example.test05.demo.config.LogAspectHandler] 15:05:35.335 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testBefore方法]:进入! 15:05:35.336 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testBefore方法]:包名为:com.example.test05.demo.controller.UserController,方法名为:testJson 15:05:35.337 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testBefore方法]:请求的url地址为:http://localhost:8086/userDO/testJson 15:05:35.337 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testAfterReturning方法]:,返回参数为:JsonData(code=0, data=UserDO(id=null, name=dbc, time=null), msg=成功) 15:05:35.338 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testAfterReturning方法]:编辑后的返回值为:UserDO(id=null, name=[testAfterReturning方法]:dbc升级版, time=Thu Jan 12 15:05:35 CST 2023) 15:05:35.338 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testAfter方法]:进入 15:05:35.339 logback [http-nio-8086-exec-5] INFO c.e.t.demo.config.LogAspectHandler - [testAfter方法]:testJson执行完成
顺序执行切面,具体顺序如下图
本文作者为DBC,转载请注明。

