具体代码
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,转载请注明。