请求生命周期
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
| Laravel | Spring Boot |
|---|---|
Nginx → PHP-FPM → public/index.php | Tomcat(内嵌)→ 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 序列化 |
关键差别要记住
- Laravel 的中间件链是「用户自己注册」的,Spring 的 Filter 链和拦截器是「组件自动装配」的 —— 你只要把类交给容器,Spring 就会在正确时机调用它。
- Java 有拦截器拦截和过滤器两个层级,刚上手时容易混淆。记住:Filter 在 Spring MVC 之外,Intercceptor 在 Spring MVC 之内。
- 整个请求链路全程共享同一个线程(默认同步处理),所以
ThreadLocal在线程内可见。异步化时这个前提会变(见 异步与队列)。
接下来,深入理解驱动这一切的核心 —— 容器与依赖注入。