Spring Boot拦截器与过滤器的核心区别
拦截器(Interceptor)
基于Spring MVC框架实现,作用于控制器方法调用前后。通过实现HandlerInterceptor接口,可覆盖preHandle、postHandle、afterCompletion方法。依赖Spring容器管理,可访问Spring上下文中的Bean(如Service层)。
过滤器(Filter)
基于Servlet规范,作用于请求进入Servlet容器前后。通过实现javax.servlet.Filter接口,覆盖doFilter方法。独立于Spring框架,无法直接使用Spring依赖注入。
关键差异
- 作用阶段:过滤器在Servlet前后,拦截器在DispatcherServlet之后。
- 依赖关系:拦截器可注入Spring Bean,过滤器需手动获取。
- 粒度控制:拦截器可精确到Controller方法,过滤器仅针对URL。
拦截器实现示例
- 定义拦截器类
java
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (request.getHeader("Authorization") == null) {
response.setStatus(401);
return false; // 中断请求
}
return true;
}
}
- 注册拦截器
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**");
}
}
过滤器实现示例
- 定义过滤器类
java
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
System.out.println("Request URI: " + ((HttpServletRequest) request).getRequestURI());
chain.doFilter(request, response); // 放行请求
}
}
- 注册过滤器
java
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<LogFilter> loggingFilter() {
FilterRegistrationBean<LogFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new LogFilter());
bean.addUrlPatterns("/*");
return bean;
}
}
实战应用场景
拦截器适用场景
- 权限验证(如JWT校验)
- 日志记录(记录Controller方法执行时间)
- 参数预处理(统一格式化请求参数)
过滤器适用场景
- 全局请求/响应编码设置
- 防止XSS攻击(过滤敏感字符)
- 静态资源缓存控制
性能与执行顺序
执行顺序
Filter -> DispatcherServlet -> Interceptor -> Controller
性能影响
- 过滤器在更底层执行,性能损耗更低。
- 拦截器因依赖Spring上下文,适合需要复杂业务逻辑的场景。
高级技巧
拦截器注入Bean
直接在拦截器类中使用@Autowired:
java
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService; // 自动注入
}
过滤器获取Spring Bean
通过WebApplicationContextUtils:
java
UserService userService = WebApplicationContextUtils
.getRequiredWebApplicationContext(request.getServletContext())
.getBean(UserService.class);