说一下SpringMVC那个什么前处理后处理,过滤器,拦截器,请求来的全流程,前端后端,Nginx,网关是怎么流转这个请求的,我现在乱的一锅粥,必须结合Tomcat模型去给我讲解
文章目录
完全理解你的感受!这个链路确实非常长,从前端到后端数据库,中间夹杂了网络层、Web 容器层(Tomcat)和框架层(Spring)的大量组件。很多概念(比如过滤器和拦截器)不仅名字像,作用看起来也很像,很容易让人觉得“乱成一锅粥”。
别慌,我们现在就把这锅粥理成一条高度清晰的“安检流水线”。
我们可以把整个请求的过程分为四个大阶段:外围网络层 ➡️ Tomcat 容器层 ➡️ Servlet 规范层 ➡️ Spring MVC 框架层。
第一阶段:外围网络层(请求的漫长旅途)
当用户在前端(浏览器/App)点击按钮,发出一个 HTTP 请求(例如 GET /api/user),请求首先要在广阔的网络世界里找到你的服务。
- 前端 (Frontend): 构造 HTTP 请求报文,通过 TCP/IP 网络发出去。
- Nginx (反向代理/负载均衡): 请求通常第一个到达的是 Nginx。
- 它的角色: 公司的“大门保安兼引路人”。它负责把静态资源(图片、前端 HTML)直接返回,如果是 API 请求,它会根据负载均衡算法,把请求分发给背后的多个网关节点。
- 网关 (API Gateway, 如 Spring Cloud Gateway):
- 它的角色: 微服务集群的“总调度中心”。在这里通常会做全局的身份认证(校验 Token)、限流(防止恶意刷接口)、以及路由转发。验证通过后,网关会将请求转发给具体的微服务实例(也就是你的 Spring Boot 应用)。
第二阶段:进入 Tomcat (服务器的内部调度)
你的 Spring Boot 应用内嵌了一个 Tomcat。当请求到达这个微服务时,其实是先交给了 Tomcat 处理。Tomcat 的核心架构分为两部分:Connector(连接器) 和 Container(容器)。
- Connector (网络接待员):
- Acceptor: 接收网关发来的 TCP 连接。
- Poller: 监听这些连接上的 I/O 事件(数据是否可读)。
- Worker Threads (工作线程池): 一旦有请求数据,Poller 会把它交给 Tomcat 线程池中的一个 Worker 线程。在这个阶段,原始的网络字节流被解析成了 Java 对象:
HttpServletRequest和HttpServletResponse。
- Container (处理车间):
- 请求被层层传递:
Engine(引擎) ➡️Host(虚拟主机) ➡️Context(你的应用上下文) ➡️Wrapper(包装具体的 Servlet)。 - Tomcat 最终要把这个请求交给 Spring MVC 的核心——
DispatcherServlet,但在交接之前,必须先经过“过滤器”。
第三阶段:Servlet 规范层(Filter 过滤器)
在请求真正进入 Spring 框架之前,它还在 Tomcat 的管辖范围内。此时,它必须穿过一条 FilterChain(过滤器链)。
- 前处理:
Filter.doFilter()方法的前半部分。在这里,我们通常做一些最基础、最通用的工作。例如:全局的跨域处理 (CORS)、字符编码转换、XSS 防护等。 - 放行: 调用
chain.doFilter(request, response),把请求传递给下一个过滤器,或者最终传给 Servlet。 - 后处理: 等后端的业务执行完,响应返回时,会沿着过滤器链反向穿过
doFilter()的后半部分。
第四阶段:Spring MVC 框架层(请求的最终目的地)
穿过过滤器后,请求终于离开了纯 Tomcat 的世界,进入了 Spring MVC 的领地。这里的核心是 DispatcherServlet(前端控制器),它像一个项目经理,负责协调所有工作。
- 找人 (HandlerMapping):
DispatcherServlet拿到请求后,去问HandlerMapping(处理器映射器):“谁能处理/api/user这个路径?”。它会返回一个 执行链 (HandlerExecutionChain),里面包含了你的 Controller 方法以及配置好的Interceptor(拦截器)。 - 拦截器前处理 (
preHandle):
- 在真正调用你的 Controller 之前,先执行拦截器的
preHandle()。 - 作用: 检查更细粒度的业务逻辑。比如:用户是否有权限访问这个特定的接口?如果没有,直接 return false,请求打回。
- 参数适配与执行 (HandlerAdapter & Controller):
HandlerAdapter负责把 HTTP 里面的 JSON 数据,转换成你 Controller 方法上的@RequestBody对象(通过HttpMessageConverter)。- 执行业务: 你的 Controller 被调用,调用 Service ➡️ DAO,查数据库,最后返回结果。
- 拦截器后处理 (
postHandle):
- Controller 执行完,但在返回结果给前端(或渲染视图)之前执行。现代前后端分离项目(全 JSON 交互)中,这个方法用得相对较少了。
- 异常与视图处理:
- 如果有异常,会被
@ExceptionHandler捕获处理。如果是正常数据,则转换回 JSON 写入HttpServletResponse。
- 拦截器最终完成 (
afterCompletion):
- 无论成功还是抛出异常,整个请求处理完毕后都会执行。非常适合用来清理 ThreadLocal 数据,防止内存泄漏,或者记录操作日志。
💡 核心答疑:Filter(过滤器) vs Interceptor(拦截器)
这也是最容易让你觉得“乱”的地方,我用一张表帮你对比清楚:
| 特性 | Filter (过滤器) | Interceptor (拦截器) |
|---|---|---|
| 归属权 | Servlet 规范(Tomcat 管理) | Spring 框架(Spring 管理) |
| 拦截范围 | 几乎所有请求(包括静态资源、CSS、JS) | 只有进入 Spring MVC 的请求(即你的 Controller) |
| 颗粒度/上下文 | 只能拿到 request 和 response |
可以拿到目标调用的 Method 和 @Annotation 等详细信息 |
| 执行顺序 | 在 Interceptor 外围(先入后出) | 在 Filter 内部(紧贴 Controller) |
总结一下整个请求的心跳轨迹(洋葱模型):浏览器 ➡️ Nginx ➡️ 网关 ➡️ Tomcat(Connector->Container) ➡️ Filter ➡️ DispatcherServlet ➡️ Interceptor ➡️ Controller(业务代码)
处理完后,再按原路层层返回。
看完这条“安检流水线”,你现在感觉思路清晰一些了吗?在这个全流程中,你平时开发中最常在哪一层写代码(比如是网关、拦截器还是 Controller)?或者哪一层的配置最让你头疼,我们可以针对性地深入聊聊。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)