Spring DispatcherServlet
外观
Spring DispatcherServlet 是 Spring Framework 中用于处理 HTTP 请求的核心组件,它作为前端控制器(Front Controller)负责将请求分发给相应的处理器(如 Controller 类),并协调视图渲染、异常处理等流程。本文将详细介绍其工作原理、配置方法及实际应用。
概述[编辑 | 编辑源代码]
DispatcherServlet 是 Java Servlet API 的扩展,实现了 `javax.servlet.http.HttpServlet` 接口。它是 Spring Web MVC 的入口点,负责以下核心任务:
- 接收所有传入的 HTTP 请求
- 通过 HandlerMapping 确定请求对应的处理器(Controller)
- 通过 HandlerAdapter 调用处理器方法
- 使用 ViewResolver 解析视图
- 处理异常并通过 HandlerExceptionResolver 返回错误响应
配置 DispatcherServlet[编辑 | 编辑源代码]
通过 web.xml 配置[编辑 | 编辑源代码]
传统方式在 `web.xml` 中声明 Servlet:
<web-app>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
通过 Java 配置[编辑 | 编辑源代码]
Spring 3.1+ 支持纯 Java 配置:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
请求处理流程[编辑 | 编辑源代码]
DispatcherServlet 处理请求的完整流程如下(可通过 `org.springframework.web.servlet.DispatcherServlet` 的 `doDispatch()` 方法查看源码实现):
1. 接收 HTTP 请求 2. 查找适用的 HandlerMapping 3. 通过 HandlerAdapter 执行处理器方法 4. 处理返回的 ModelAndView 或响应体 5. 解析视图(如需要) 6. 渲染视图并返回响应
数学表示请求映射关系:
核心组件交互[编辑 | 编辑源代码]
DispatcherServlet 依赖多个协作组件:
组件 | 职责 |
---|---|
HandlerMapping | 确定请求对应的处理器 |
HandlerAdapter | 执行处理器方法 |
ViewResolver | 将逻辑视图名解析为实际视图 |
HandlerExceptionResolver | 处理控制器抛出的异常 |
LocaleResolver | 解析客户端区域设置 |
实际案例[编辑 | 编辑源代码]
基本控制器示例[编辑 | 编辑源代码]
@Controller
public class HomeController {
@GetMapping("/greet")
public String greet(Model model) {
model.addAttribute("message", "Hello, Spring MVC!");
return "welcome"; // 视图名
}
}
对应的视图文件 `welcome.jsp`:
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head><title>Greeting</title></head>
<body>
<h1>${message}</h1>
</body>
</html>
访问 `/greet` 的输出:
{{{1}}}
REST 控制器示例[编辑 | 编辑源代码]
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}
高级主题[编辑 | 编辑源代码]
自定义 DispatcherServlet[编辑 | 编辑源代码]
可通过继承扩展默认行为:
public class CustomDispatcherServlet extends DispatcherServlet {
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
// 前置处理
super.doDispatch(request, response);
// 后置处理
}
}
异步请求处理[编辑 | 编辑源代码]
Spring MVC 支持异步请求处理:
@GetMapping("/async")
public Callable<String> asyncProcessing() {
return () -> {
Thread.sleep(2000); // 模拟长时间任务
return "async-result";
};
}
常见问题[编辑 | 编辑源代码]
页面模块:Message box/ambox.css没有内容。
若遇到 404 错误,检查:
|
性能考量[编辑 | 编辑源代码]
- 默认情况下,DispatcherServlet 是线程安全的
- 避免在控制器中维护状态
- 对于高并发场景,考虑:
* 使用异步处理 * 优化视图解析 * 缓存静态资源