Spring Boot 拦截器(Interceptor)与过滤器(Filter)深度解析与实战指南

Spring Boot 拦截器(Interceptor)与过滤器(Filter)深度解析与实战指南

一、核心概念对比

维度过滤器(Filter)拦截器(Interceptor)
规范层级Servlet 规范(J2EE 标准)Spring MVC 框架机制
作用范围所有请求仅处理 Controller 层请求
执行时机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. Filter 的实现

  • 代码示例
  @Component
  @WebFilter(urlPatterns = "/*")
  public class LogFilter implements Filter {
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
          long start = System.currentTimeMillis();
          chain.doFilter(request, response); // 必须调用以传递请求
          System.out.println("请求耗时:" + (System.currentTimeMillis() - start) + "ms");
      }
  }
  • 注册方式
  • 注解@WebFilter + @ServletComponentScan
  • 配置类:通过 FilterRegistrationBean 设置优先级
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<LogFilter> loggingFilter() {
        FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new LogFilter());
        registration.addUrlPatterns("/*");
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 设置优先级
        return registration;
    }
}

2. Interceptor 的实现

  • 代码示例
  @Component
  public class LogInterceptor implements HandlerInterceptor {
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
          System.out.println("PreHandle: 请求路径=" + request.getRequestURI());
          return true; // 返回 true 表示继续执行后续流程
      }

      @Override
      public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
          System.out.println("PostHandle: 请求处理完成");
      }

      @Override
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
          System.out.println("AfterCompletion: 请求流程完全结束");
      }
  }
  • 注册方式
  @Configuration
  public class WebConfig implements WebMvcConfigurer {
      private final LogInterceptor logInterceptor;

      public WebConfig(LogInterceptor logInterceptor) {
          this.logInterceptor = logInterceptor;
      }

      @Override
      public void addInterceptors(InterceptorRegistry registry) {
          registry.addInterceptor(logInterceptor)
                  .addPathPatterns("/**") // 拦截所有路径
                  .excludePathPatterns("/public/**"); // 排除公共路径
      }
  }

四、实战应用场景

1. Filter 的典型应用

  • 跨域处理
  @Component
  @WebFilter("/*")
  public class CorsFilter implements Filter {
      @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
          HttpServletResponse response = (HttpServletResponse) res;
          HttpServletRequest request = (HttpServletRequest) req;
          response.setHeader("Access-Control-Allow-Origin", "*");
          response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
          if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
              response.setStatus(HttpServletResponse.SC_OK);
          } else {
              chain.doFilter(req, res);
          }
      }
  }
  • 字符编码转换
  @Component
  @WebFilter("/*")
  public class EncodingFilter implements Filter {
      @Override
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
          req.setCharacterEncoding("UTF-8");
          res.setCharacterEncoding("UTF-8");
          chain.doFilter(req, res);
      }
  }

2. Interceptor 的典型应用

  • 权限校验
  @Component
  public class AuthInterceptor implements HandlerInterceptor {
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
          String token = request.getHeader("Authorization");
          if (token == null || !isValidToken(token)) {
              response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "未授权");
              return false;
          }
          return true;
      }

      private boolean isValidToken(String token) {
          // 实际业务中校验 token 有效性
          return true;
      }
  }
  • 性能监控
  @Component
  public class PerformanceInterceptor implements HandlerInterceptor {
      @Override
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
          request.setAttribute("startTime", System.currentTimeMillis());
          return true;
      }

      @Override
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
          long duration = System.currentTimeMillis() - (Long) request.getAttribute("startTime");
          System.out.println("请求耗时:" + duration + "ms");
      }
  }

五、注意事项与最佳实践

1. Filter 与 Interceptor 的选择

  • Filter 适用于全局性、与业务无关的处理(如跨域、编码、日志)。
  • Interceptor 适用于与业务逻辑相关的处理(如权限校验、参数预处理)。

2. 异常处理

  • Filter:无法直接使用 Spring 的异常处理机制,需手动捕获并处理异常。
  • Interceptor:可通过 @ControllerAdvice 统一处理异常。

3. 性能优化

  • Filter:由于作用于所有请求,需避免在 doFilter 中执行复杂逻辑。
  • Interceptor:建议在 preHandle 中尽量减少耗时操作,避免影响请求吞吐量。

4. 优先级控制

  • Filter:通过 FilterRegistrationBean.setOrder() 设置优先级。
  • Interceptor:通过 InterceptorRegistry.addInterceptor() 注册顺序控制执行顺序。

六、总结

特性Filter 适用场景Interceptor 适用场景
全局处理✅ 跨域、编码、日志❌ 仅处理 Controller 请求
业务逻辑处理❌ 与业务无关✅ 权限校验、参数预处理
依赖 Spring 容器❌ 不依赖✅ 可注入 Bean
异常处理❌ 需手动处理✅ 支持 @ControllerAdvice
执行顺序✅ 最先执行(DispatcherServlet 之前)✅ 在 DispatcherServlet 之后执行

通过合理选择 Filter 和 Interceptor,开发者可以高效实现请求处理的分层与解耦,提升系统的可维护性和扩展性。

© 版权声明
THE END
喜欢就支持一下吧
点赞11赞赏 分享