happy birthday BNTang!

Springboot打印接口耗时

Springboot 打印 接口 耗时

三种方式 下面为大家一一对应

1 aop切面的方式 

1.1 实现思路

  1. 引入aop依赖
  2. 自定义注解
  3. 定义切面,采用环绕通知

1.2 代码实现

1)引入依赖

        <!--aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2)自定义注解LogAnnotation

/**
 * 日志注解
 * METHOD 方法上 type 类上
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {

    /**
     * 模块
     */
    String module() default "";

    /**
     * 简单描述接口的作用
     */
    String operation() default "";
}

3)定义切面

简单分析一下切面实现的功能:

/**
 * @author : look-word
 * 2022-07-27 16:03
 **/
@Slf4j
@Aspect
@Component
public class LogAspect {

    /**
     * 切入点
     */
    @Pointcut("@annotation(look.word.reggie.common.aop.LogAnnotation)")
    public void logPointCut() {
    }

    /**
     * 环绕通知
     *
     * @param point 连接点
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        recordLog(point, time);
        return result;
    }

    private void recordLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取当前方法
        Method method = signature.getMethod();
        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
        log.info("=====================log start================================");
        log.info("module:{}", logAnnotation.module());
        log.info("operation:{}", logAnnotation.operation());

        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        log.info("request method:{}", className + "." + methodName + "()");

        //请求的参数
        Object[] args = joinPoint.getArgs();
        Stream<?> stream = ArrayUtils.isEmpty(args) ? Stream.empty() : Arrays.stream(args);
        List<Object> logArgs =
                stream.filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))).collect(Collectors.toList());
        String params = JSON.toJSONString(logArgs);
        log.info("params:{}", params);

        //获取request 设置IP地址
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        log.info("ip:{}", IpUtils.getIpAddr(request));
        
        log.info("execute time : {} ms", time);
        log.info("=====================log end================================");
    }
}

1.3 功能测试

在接口上添加注解即可,还有描述信息

image-20220809221006438

image-20220809221223447

2 过滤器的方式

这种方式简单点 但是可配置性不高

注意:一定得扫描到spring容器中

创建一个类 实现 filter接口

  • init:该方法是对filter对象进行初始化的方法,仅在容器初始化filter对象结束后被调用一次,参数FilterConfig可以获得filter的初始化参数;
  • doFilter:可以对request和response进行<u>预处理</u>其中FilterChain可以将处理后的request和response对象传递到过滤链上的下一个资源。
  • destroy():该方法在容器销毁对象前被调用。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@Component
public class LogFilter implements Filter {

    private static final Logger LOG = LoggerFactory.getLogger(LogFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 打印请求信息
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        LOG.info("------------- LogFilter 开始 -------------");
        LOG.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        LOG.info("远程地址: {}", request.getRemoteAddr());

        long startTime = System.currentTimeMillis();
        filterChain.doFilter(servletRequest, servletResponse);
        LOG.info("------------- LogFilter 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);
    }
}

结果
img

总结

1.过滤器用来实现通用的功能,减少代码冗余,提高可维护性;
2.一个过滤器可以配置给多个资源使用(编码过滤器);
3.一个资源也可以配置多个过滤器,按照配置顺序调用。

3 拦截器的方式

如果不懂 请先看了 介绍再来

拦截器的介绍

话不说多 直接上代码

创建拦截器

/**
 * 拦截器:Spring框架特有的,常用于登录校验,权限校验,请求日志打印 /login
 * @author : look-word
 * 2022-06-26 13:55
 **/
@Component
public class LogInterceptor implements HandlerInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(LogInterceptor.class);

        
    @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         // 打印请求信息
         LOG.info("------------- LogInterceptor 开始 -------------");
         LOG.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
         LOG.info("远程地址: {}", request.getRemoteAddr());

         long startTime = System.currentTimeMillis();
         request.setAttribute("requestStartTime", startTime);
         return true;
     }

     @Override
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
         long startTime = (Long) request.getAttribute("requestStartTime");
         LOG.info("------------- LogInterceptor 结束 耗时:{} ms -------------", System.currentTimeMillis() - startTime);
     }
}

注册拦截器

把我们的拦截器 注册到 拦截器链中

/**
 * @author : look-word
 * 2022-06-26 14:03
 **/
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {

    @Resource
    private LogInterceptor logInterceptor;
    /**
     * 注册拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                .addInterceptor(logInterceptor)
                .addPathPatterns("/**")// 对那些接口拦截
                .excludePathPatterns("/login");// 对哪些接机口放行
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

测试结果

img

posted @ 2022-08-09 22:14  look-word  阅读(900)  评论(0编辑  收藏  举报