type
Post
status
Published
date
Mar 2, 2021
slug
summary
接口耗时是应用监控中重要的指标,可以看出应用处理能力;本文介绍拦截器和过滤器两种方式打印接口耗时统计
tags
项目方案
category
技术分享
icon
password

拦截器方式

Interceptor 拦截器,用于对 Controller 进行前置、后置处理
  • 底层基于 AOP实现,与环绕通知类似
  • 和过滤器 Filter 作用类似,但只用于 SpringMVC 中的控制器
要使用拦截器,只需要实现HandlerInterceptor 接口,并重写其中的处理方法:
  • 前置处理方法是 preHandle,返回一个返回一个布尔值
    • 是请求阻断的开关,当返回false时请求将不再继续往下传递
  • postHandle 是后置处理方法,在目标方法执行之后,资源已被 SpringMVC 处理,视图对象还未返回
统计接口耗时主要在这两个方法中进行统计
   private static final Logger LOG = LoggerFactory.getLogger(LogInterceptor.class);    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //request参数中可以获得请求相关的信息        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);   }

过滤器方式

过滤器是 Servlet 容器层面,任何 Java Web 工程都能使用
@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); } }
Spring AOP 打印接口日志转账案例-引入事务和AOP进行改造