首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring MVC攔截器實現日志記錄與性能監控完整示例 Spring MVC攔截器實現日志記錄與性能監控完整示例

     編輯:Java 相關知識

Spring MVC HandlerInterceptor 提供三個切面方法:preHandle、postHandle、afterCompletion,可實現通用日志記錄、執行耗時統計、異常捕獲等橫切關注點。本文演示基於 SLF4J 的完整實現。

一、攔截器實現

package org.xs.demo1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;

public class LogInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(LogInterceptor.class);
    private static final ThreadLocal START_TIME_THREAD_LOCAL = new NamedThreadLocal<>("ThreadLocal StartTime");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        long start = System.currentTimeMillis();
        START_TIME_THREAD_LOCAL.set(start);
        log.info("開始計時: {}", new SimpleDateFormat("HH:mm:ss.SSS").format(start));
        return true; // true=繼續執行,false=中斷
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        if (modelAndView != null) {
            log.info("ViewName: {}", modelAndView.getViewName());
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        long start = START_TIME_THREAD_LOCAL.get();
        long end = System.currentTimeMillis();
        log.info("訪問地址: {}, 請求方式: {}", request.getRequestURI(), request.getMethod());
        log.info("計時結束: {}, 耗時: {} ms", new SimpleDateFormat("HH:mm:ss.SSS").format(end), end - start);

        // 可選:保存訪問日志到數據庫
        // LogUtils.saveLog(request, handler, ex, null);
    }
}

二、Spring MVC 配置註冊

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/> <!-- 攔截所有請求 -->
        <bean class="org.xs.demo1.LogInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

或 Java Config:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
    }
}

三、運行效果驗證

訪問 https://localhost:8080/demo1/hello/list2,控制台輸出:

[INFO ] 14:30:45.123 LogInterceptor - 開始計時: 14:30:45.123
[INFO ] 14:30:45.125 LogInterceptor - ViewName: hello/list
[INFO ] 14:30:45.126 LogInterceptor - 訪問地址: /demo1/hello/list2, 請求方式: GET
[INFO ] 14:30:45.126 LogInterceptor - 計時結束: 14:30:45.126, 耗時: 3 ms

控制台日志輸出截圖

四、進階擴展場景

  1. 權限校驗:preHandle 中檢查 Session/Token,失敗返回 false 並重定向登錄頁
  2. 接口限流:結合 Guava RateLimiter 或 Redis 計數器,超限返回 429
  3. 參數清洗:preHandle 中統一 XSS 過濾、SQL 注入防護
  4. 異常統一處理:afterCompletion 中 ex != null 記錄錯誤日志、發送告警
  5. 分布式追蹤:生成 TraceId 存入 ThreadLocal,傳遞給下游服務

五、攔截器 vs 過濾器 對比

維度HandlerInterceptorFilter
屬於Spring MVC 體系Servlet 規範
攔截範圍僅 Controller 處理流程所有進入容器請求(含靜態資源)
獲取上下文方便獲取 Handler、ModelAndView僅 ServletRequest/Response
配置方式Spring 配置類/XMLweb.xml 或 @WebFilter
執行順序Filter → Interceptor → Controller最外層

六、最佳實踐建議

  • 使用 NamedThreadLocal 避免線程池復用導致數據洩漏
  • preHandle 返回 false 時務必手動響應(如 response.sendRedirect()),否則客戶端無響應
  • 耗時統計用 System.nanoTime() 精度更高
  • 生產環境日志級別建議 INFO,關鍵路徑 DEBUG
  • 大量日志輸出考慮異步 Appender (Logback AsyncAppender) 避免阻塞業務線程

掌握 HandlerInterceptor 三階段生命周期,能優雅實現日志、監控、安全等橫切功能,保持控制器代碼純淨專注業務邏輯。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved