赞
踩
如何在 Spring Boot 2.0 中使用 AOP 切面统一处理请求日志,打印进出参相关参数。
可以看到,每个对于每个请求,开始与结束一目了然,并且打印了以下参数:
POST
, GET
, 还是 DELETE
等;- <!-- aop 依赖 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-aop</artifactId>
- </dependency>
-
- <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.47</version>
- </dependency>
在配置 AOP 切面之前,我们需要了解下 aspectj
相关注解的作用:
- package com.zhx.guides.collect.web.aspect;
-
- import com.alibaba.fastjson.JSONObject;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.*;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Component;
- import org.springframework.web.context.request.RequestContextHolder;
- import org.springframework.web.context.request.ServletRequestAttributes;
-
- import javax.servlet.http.HttpServletRequest;
-
- /**
- * @Class WebLogAspect
- * @Author 作者姓名:悟能的师兄
- * @Version 1.0
- * @Date 创建时间:2020-03-03 10:05
- * @Copyright Copyright by
- * @Direction 类说明
- */
- @Aspect
- @Component
- public class WebLogAspect {
-
- private final static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
-
- /** 以 controller 包下定义的所有请求为切入点 */
- @Pointcut("execution(public * com.zhx.guides.collect.interfaces.controller..*.*(..))")
- public void webLog() {}
-
- /**
- * 在切点之前织入
- * @param joinPoint
- * @throws Throwable
- */
- @Before("webLog()")
- public void doBefore(JoinPoint joinPoint) throws Throwable {
- // 开始打印请求日志
- ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- HttpServletRequest request = attributes.getRequest();
-
- // 打印请求相关参数
- logger.info("======================= Start ======================");
- // 打印请求 url
- logger.info("URL : {}", request.getRequestURL().toString());
- // 打印 Http method
- logger.info("HTTP Method : {}", request.getMethod());
- // 打印调用 controller 的全路径以及执行方法
- logger.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
- // 打印请求的 IP
- logger.info("IP : {}", request.getRemoteAddr());
- // 打印请求入参
- try {
- Object requestParam = joinPoint.getArgs();
- logger.info("参数 : {}", JSONObject.toJSONString(requestParam) );
- }catch (Exception e){
- logger.info("参数打印失败,异常: {}", e.getMessage() );
- }
- }
-
- /**
- * 在切点之后织入
- * @throws Throwable
- */
- @After("webLog()")
- public void doAfter() throws Throwable {
- logger.info("======================= End ======================");
- }
-
- /**
- * 环绕
- * @param proceedingJoinPoint
- * @return
- * @throws Throwable
- */
- @Around("webLog()")
- public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
- long startTime = System.currentTimeMillis();
- Object result = proceedingJoinPoint.proceed();
- // 打印出参
- logger.info("返回值 : {}", JSONObject.toJSONString(result));
- // 执行耗时
- logger.info("耗时 : {} ms", System.currentTimeMillis() - startTime);
- return result;
- }
-
- }
我们通过 @Aspect
声明了 WebLogAspect.java
为切面类,之后,通过 @Pointcut
定义了打印请求日志的切点,切点为 com.zhx.guides.collect.interfaces.controller
包下所有的请求接口。
切点定义好后,我们通过 @Before
在切点之前打印请求的相关参数,通过 @Around
打印了请求接口的耗时时间,最后通过 @After
做了请求的收尾工作。
到这里,切面相关的代码就完成了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。