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 规范的底层组件,适合通用请求处理(如跨域、日志),作用范围更广但灵活性较低。
两者可以 同时使用,形成更复杂的处理链(例如:过滤器处理跨域,拦截器处理权限验证)。