Spring Boot 中 Filter 的加载机制 和 Servlet 容器(如 Tomcat)的请求处理流程 。下面我来系统性地解释为什么请求会先经过 AuthFilter,以及整个流程背后的原理。
一、请求处理的基本流程(Servlet 规范)
在基于 Servlet 的 Web 应用(包括 Spring Boot 内嵌 Tomcat)中,所有 HTTP 请求都会先进入 Servlet 容器(如 Tomcat),然后:
- 容器根据 URL 匹配对应的 Filter 链(Filter Chain)
- 按照注册顺序依次执行每个 Filter 的
doFilter()方法 - 所有 Filter 执行完后,才会将请求交给目标 Servlet (在 Spring Boot 中通常是
DispatcherServlet) DispatcherServlet再将请求分发给对应的 Controller
因此:Filter 是在 Controller 之前执行的,这是 Servlet 规范决定的。
二、Spring Boot 如何注册 Filter?
Spring Boot 提供了多种方式注册自定义 Filter,常见的是通过 @Bean + FilterRegistrationBean:
@Bean
public FilterRegistrationBean<AuthFilter> authFilter() {
FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new AuthFilter());
registration.setOrder(3); // 设置执行顺序
registration.addUrlPatterns("/*"); // 匹配所有请求
return registration;
}
setOrder(3)表示该 Filter 在 Filter 链中的优先级(数字越小越先执行)- Spring Boot 启动时会自动扫描并注册这些
FilterRegistrationBean - 最终,这些 Filter 会被注册到内嵌的 Tomcat Servlet 容器中
注意:除了自定义 Filter,Spring Security、字符编码 Filter(CharacterEncodingFilter)等也会被自动注册,它们也有各自的 Order。
三、Filter Chain 的执行顺序
Filter 的执行顺序由 @Order 注解或 FilterRegistrationBean.setOrder() 决定。例如:
| Order | Filter 名称 | 作用 |
|---|---|---|
| 1 | CharacterEncodingFilter | 设置请求/响应编码 |
| 2 | SomeLoggingFilter | 记录请求日志 |
| 3 | AuthFilter | 执行身份认证逻辑 ✅ |
| ... | Other Filters | 其他过滤器 |
| 最后 | DispatcherServlet | 分发请求到 Controller |
所以当一个请求进来时:
- Tomcat 构建匹配该 URL 的 Filter 链
- 按 Order 从小到大依次调用每个 Filter 的
doFilter() - 到达
AuthFilter(Order=3)时,执行认证逻辑:- 如果认证失败 → 直接返回 401/403,不再继续调用 chain.doFilter()
- 如果认证成功 → 调用
chain.doFilter(request, response),继续下一个 Filter 或进入 Controller
四、为什么"验证通过后才会到达 Controller"?
因为 Filter 是 前置拦截器 。只有当所有 Filter 都调用了 chain.doFilter(),请求才会最终传递给 DispatcherServlet,进而路由到你的 @RestController。
如果 AuthFilter 发现 token 无效,它可以直接:
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return; // 不调用 chain.doFilter()
这样请求就不会继续向下传递,Controller 根本不会被执行。
五、总结:关键点
| 关键点 | 说明 |
|---|---|
| Filter 是 Servlet 规范的一部分 | 所有请求必须先经过 Filter 链 |
| Spring Boot 自动注册 Filter | 通过 FilterRegistrationBean 或 @WebFilter |
| 执行顺序由 Order 决定 | 数字越小越先执行 |
| AuthFilter 在 Order=3 位置 | 在它之前的 Filter 已执行,之后的还没执行 |
| 认证失败可中断链路 | 不调用 chain.doFilter() 即可阻止请求到达 Controller |
补充建议
- 如果使用 Spring Security ,通常不需要手写
AuthFilter,因为 Security 本身就是一个强大的 Filter(springSecurityFilterChain),且 Order 非常靠前(默认 -100)。 - 手动实现认证 Filter 适用于轻量级场景或定制需求。