文档站点
Skip to content

请求生命周期 ​

Laravel 的请求从 public/index.php 进入,经过 Kernel、中间件、路由,最后到控制器。Spring Boot 的请求路径类似,但没有 index.php —— 一切由框架内置的「过滤器链 + DispatcherServlet」接管。

一次 HTTP 请求的完整旅程 ​

浏览器 / 客户端
   │  HTTP 请求
   ▼
[1] 内嵌 Tomcat(监听 8080)
   │
   ▼
[2] Servlet Filter 链
   │   ← 对应 Laravel 的全局中间件(web 组)
   │     Spring Security 的过滤器也挂在这里
   ▼
[3] DispatcherServlet
   │   ← Spring MVC 的前端控制器,相当于 Laravel 的 Router
   │
   ▼
[4] HandlerMapping  → 找到处理该 URL 的 Controller 方法
   │
   ▼
[5] HandlerInterceptor(前置/后置拦截器)
   │   ← 对应 Laravel 的路由中间件(before / after)
   ▼
[6] 参数解析 & 校验(@Valid)
   │   ← 相当于 Laravel 的 Request 依赖注入 + validate()
   ▼
[7] Controller 方法执行(业务逻辑)
   │
   ▼
[8] 返回值 → 消息转换器 → 序列化(JSON 等)
   │   ← 相当于 Laravel 的 Response / Resource 序列化
   ▼
[9] 响应返回 → 经过 Filter 后置逻辑 → 浏览器

与 Laravel 生命周期逐段对照 ​

请求进入:Tomcat ⇄ PHP-FPM ​

LaravelSpring Boot
Nginx → PHP-FPM → public/index.phpTomcat(内嵌)→ Servlet 容器

Tomcat 是「Servlet 容器」,负责接收 HTTP 请求、解析、创建 HttpServletRequest 对象,然后交给后面的 Spring MVC。

过滤器:Filter ⇄ 全局中间件 ​

java
package com.example.demo.config;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;

@Component
public class RequestTimeFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        long start = System.currentTimeMillis();
        chain.doFilter(request, response);           // 放行,进入后续处理
        long cost = System.currentTimeMillis() - start;
        ((HttpServletResponse) response).setHeader("X-Process-Time", String.valueOf(cost));
    }
}

TIP

Filter 是 Servlet 层面的,对所有请求生效,是 Spring Security 这类「拦全局」组件的老家。它比 Spring MVC 的拦截器更底层。

路由分发:DispatcherServlet ⇄ Router ​

Spring MVC 的核心。它根据 URL + 方法 + 注解,在「路由表」里找到对应控制器方法。这个「路由表」不需要你维护,注解声明即注册(见 路由)。

java
@RestController
public class PostController {
    @GetMapping("/posts/{id}")     // ← 声明即注册路由
    public Post show(@PathVariable Long id) {
        ...
    }
}

拦截器:HandlerInterceptor ⇄ 路由中间件 ​

java
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 相当于中间件的 before 逻辑;返回 false 则终止请求
        return true;
    }

    @Override
    public void postHandle(...) {
        // 相当于 after 逻辑(视图渲染前)
    }

    @Override
    public void afterCompletion(...) {
        // 请求结束后(可在这里记录耗时)
    }
}

拦截器比 Filter 更「面向 MVC」,能拿到具体的 Controller 方法信息。详见 中间件。

控制器:Controller ⇄ Controller ​

和 Laravel 控制器概念几乎一致,区别在于方法签名靠参数解析器自动填充(@PathVariable、@RequestParam、@RequestBody 等),不需要像 PHP 那样手动从 $request 里取。详见 请求(参数绑定)。

响应:消息转换器 ⇄ Resource 序列化 ​

控制器方法返回什么,Spring 就交给 HttpMessageConverter 序列化:

  • 返回 String → 纯文本
  • 返回对象 + @RestController → Jackson 自动转 JSON
  • 返回 ResponseEntity<T> → 可自定义状态码、头(详见 响应)

生命周期里重要的三个「时点」 ​

时点干的事类比 Laravel
请求进入后、进路由前Filter(全局)HandleCors、EncryptCookies 等全局中间件
找到控制器方法后、执行前Interceptor.preHandle路由中间件 before
控制器返回后、响应前Interceptor.postHandle + 消息转换器路由中间件 after + Resource 序列化

关键差别要记住 ​

  1. Laravel 的中间件链是「用户自己注册」的,Spring 的 Filter 链和拦截器是「组件自动装配」的 —— 你只要把类交给容器,Spring 就会在正确时机调用它。
  2. Java 有拦截器拦截和过滤器两个层级,刚上手时容易混淆。记住:Filter 在 Spring MVC 之外,Intercceptor 在 Spring MVC 之内。
  3. 整个请求链路全程共享同一个线程(默认同步处理),所以 ThreadLocal 在线程内可见。异步化时这个前提会变(见 异步与队列)。

接下来,深入理解驱动这一切的核心 —— 容器与依赖注入。

面向 PHP / Laravel 开发者的 Spring Boot 中文文档