以下是对Spring Boot中过滤器(Filter)与拦截器(Interceptor)的深度对比及实战应用分析,结合技术原理和实际场景展开:
一、核心概念对比
维度 | 过滤器(Filter) | 拦截器(Interceptor) |
---|---|---|
规范层级 | Servlet规范(J2EE标准),属于Web容器层面 | Spring MVC框架机制,基于AOP实现 |
作用范围 | 所有请求(包括静态资源如HTML/CSS/JS) | 仅处理Controller层请求(由DispatcherServlet映射的请求) |
执行时机 | 在DispatcherServlet之前执行 | 在DispatcherServlet之后、Controller方法调用前/后执行 |
依赖关系 | 不依赖Spring容器 | 完全集成Spring IOC,可注入Bean |
异常处理 | 无法直接使用Spring的@ControllerAdvice | 可通过@ControllerAdvice统一处理异常 |
生命周期管理 | 由Servlet容器管理(init/destroy) | 由Spring管理,可通过@Autowired获取Bean |
执行流程示意图:
HTTP Request
↓
Filter Chain (doFilter) → 字符编码/XSS过滤/日志统计等(全局处理)
↓
DispatcherServlet
↓
Interceptor.preHandle → 权限校验/接口限流等(业务相关)
↓
Controller Method
↓
Interceptor.postHandle → 响应数据封装/日志补充
↓
View Rendering (如有)
↓
Interceptor.afterCompletion → 资源清理
↓
Filter Chain → 响应压缩/跨域处理
二、技术实现差异
1. 过滤器的实现
代码示例:
@Component
@WebFilter(urlPatterns = "/*")
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
chain.doFilter(request, response); // 必须调用以传递请求
System.out.println("请求耗时:" + (System.currentTimeMillis() - start) + "ms");
}
}
注册方式:
- 注解:
@WebFilter + @ServletComponentScan
- 配置类:通过
FilterRegistrationBean
设置优先级(setOrder(1)
)
2. 拦截器的实现
代码示例):
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("Authorization");
if (!validateToken(token)) {
response.setStatus(401);
return false; // 中断请求
}
return true;
}
}
注册方式:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/login");
}
}
三、应用场景选择
1. 优先使用过滤器的场景
- 全局请求处理:字符编码设置(
CharacterEncodingFilter
)、跨域处理(CORS) - 安全防御:XSS攻击过滤、SQL注入拦截
- 性能监控:请求耗时统计(需注意静态资源可能影响数据准确性)
2. 优先使用拦截器的场景
- 业务相关控制:JWT Token校验、接口权限控制
- 数据预处理:参数校验(如非空检查)、请求日志记录(关联用户ID)
- 响应后处理:统一数据格式封装(如ResultVO)、敏感信息脱敏
3. 组合使用案例
请求
↓
过滤器(全局日志)
↓
拦截器(权限校验)
↓
Controller
↓
拦截器(数据脱敏)
↓
过滤器(响应压缩)
四、实战注意事项
-
执行顺序控制:
- 过滤器优先级通过
FilterRegistrationBean.setOrder()
控制(值越小优先级越高) - 拦截器执行顺序由注册顺序决定(
addInterceptor
的调用顺序)
- 过滤器优先级通过
-
性能优化:
- 过滤器适合处理与业务无关的高频操作(如GZIP压缩)
- 拦截器避免在
preHandle
中执行耗时操作(如远程调用)
-
异常处理差异:
- 过滤器异常需自行处理(如跳转错误页面)
- 拦截器异常可通过
@ControllerAdvice + @ExceptionHandler
统一捕获
五、总结建议
决策维度 | 选择建议 |
---|---|
是否需要Spring上下文 | 需要 → 拦截器;不需要 → 过滤器 |
是否处理静态资源 | 需要 → 过滤器;仅API → 拦截器 |
是否需要精细控制 | AOP切面 → 拦截器;底层协议处理 → 过滤器 |
最佳实践:
- 简单场景优先使用拦截器(权限校验)
- 复杂场景组合使用(日志+权限+响应处理)
- 生产环境通过
Filter
和Interceptor
的@Order
明确执行顺序
通过合理选择过滤器和拦截器,开发者可以构建高可维护性的Web应用架构。