Spring 攔截器(Interceptor)與過濾器(Filter)對比
核心對比表格
對比維度 | 攔截器(Interceptor) | 過濾器(Filter) |
---|---|---|
定義 | Spring MVC 提供的組件,集成于 Spring 處理器鏈。 | Servlet 規范組件,屬于 Java EE 標準。 |
作用范圍 | 僅限于映射到 Controller 的請求(如 @RequestMapping 處理的請求)。 | 所有請求(包括靜態資源、非 Spring 處理的請求)。 |
執行時機 | 在 Spring MVC 處理器鏈中執行(Controller 方法前后)。 | 在 Servlet 容器啟動時初始化,請求到達時立即執行(在 Spring MVC 處理器鏈之前)。 |
生命周期 | 由 Spring 容器管理(默認單例),無顯式 init() 和 destroy() 方法。 | 由 Servlet 容器管理,需實現 init() 和 destroy() 方法。 |
核心方法 | preHandle() , postHandle() , afterCompletion() | init() , doFilter() , destroy() |
配置方式 | 通過 WebMvcConfigurer.addInterceptors() 注冊。 | 通過 FilterRegistrationBean 或 web.xml 注冊。 |
典型使用場景 | 權限驗證、日志記錄、請求參數校驗、與 Spring 服務層交互。 | 跨域處理(CORS)、日志記錄、請求壓縮、靜態資源攔截、通用 HTTP 頭處理。 |
依賴注入支持 | 支持 @Autowired 等 Spring 依賴注入。 | 需通過 FilterRegistrationBean 或 @Component 顯式注入。 |
執行順序控制 | 通過 order() 方法設置優先級(數值越小優先級越高)。 | 通過 FilterRegistrationBean.setOrder() 或 web.xml 的聲明順序控制。 |
異常處理 | 通過 afterCompletion() 處理異常(需配合 HandlerExceptionResolver )。 | 需在 doFilter() 中通過 try-catch 捕獲異常。 |
性能影響 | 僅針對 Controller 請求,性能影響較小。 | 針對所有請求,可能影響性能(如頻繁的靜態資源請求)。 |
關鍵區別示例
場景 1:身份驗證
- 攔截器:適合與 Spring 服務層結合,如通過
@Autowired
注入UserService
驗證 Token。 - 過濾器:適合通用 Token 驗證(如 JWT),攔截所有請求(包括登錄接口)。
場景 2:日志記錄
- 攔截器:記錄 Controller 方法級別的執行時間。
- 過濾器:記錄所有請求的 URL、響應時間(包括靜態資源)。
場景 3:異常處理
- 攔截器:通過
afterCompletion()
統計接口錯誤率。 - 過濾器:需在
doFilter()
中通過try-catch
處理異常。
代碼示例對比
攔截器配置
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).order(1).addPathPatterns("/**").excludePathPatterns("/login");}
}
過濾器配置
@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<CorsFilter> corsFilterRegistration() {FilterRegistrationBean<CorsFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new CorsFilter());registration.addUrlPatterns("/*");registration.setOrder(2);return registration;}
}
生命周期對比
階段 | 攔截器(Interceptor) | 過濾器(Filter) |
---|---|---|
初始化 | 由 Spring 容器自動初始化,無 init() 方法。 | 需實現 init() 方法,在 Servlet 容器啟動時調用。 |
請求處理 | preHandle() → Controller → postHandle() → afterCompletion() | doFilter() 中處理請求(需顯式調用 chain.doFilter() )。 |
銷毀 | 由 Spring 容器管理,無 destroy() 方法。 | 需實現 destroy() 方法,在應用關閉時調用。 |
執行流程圖
客戶端請求 →
├─ Filter 的 doFilter() →
│ ├─ Filter 前置處理 →
│ │ └─ 繼續 FilterChain →
│ │ ├─ Interceptor 的 preHandle() →
│ │ │ └─ 攔截器前置處理 →
│ │ │ └─ Controller 方法執行 →
│ │ │ └─ Interceptor 的 postHandle() →
│ │ │ └─ 攔截器后置處理 →
│ │ └─ Interceptor 的 afterCompletion() →
│ │ └─ 攔截器完成處理
│ └─ Filter 后置處理
└─ 響應返回
選擇建議
-
使用攔截器的場景:
- 需要與 Spring 上下文深度集成(如依賴注入服務層)。
- 僅需處理 Controller 映射的請求(如
/api/**
)。 - 需要細粒度控制請求生命周期(如方法執行前后校驗)。
-
使用過濾器的場景:
- 需要攔截所有請求(包括靜態資源、非 Spring 處理的請求)。
- 需要直接操作請求/響應對象(如修改 HTTP 頭、壓縮響應)。
- 需要在請求到達 Spring 處理器鏈之前執行邏輯(如統一日志記錄)。
總結
- 攔截器 是 Spring MVC 的高級組件,適合與 Spring 生態深度集成,處理 Controller 層的業務邏輯。
- 過濾器 是 Servlet 規范的底層組件,適合通用請求處理(如跨域、日志),作用范圍更廣但靈活性較低。
兩者可以 同時使用,形成更復雜的處理鏈(例如:過濾器處理跨域,攔截器處理權限驗證)。