跳转到内容

Spring DispatcherServlet

来自代码酷


Spring DispatcherServletSpring Framework 中用于处理 HTTP 请求的核心组件,它作为前端控制器(Front Controller)负责将请求分发给相应的处理器(如 Controller 类),并协调视图渲染、异常处理等流程。本文将详细介绍其工作原理、配置方法及实际应用。

概述[编辑 | 编辑源代码]

DispatcherServlet 是 Java Servlet API 的扩展,实现了 `javax.servlet.http.HttpServlet` 接口。它是 Spring Web MVC 的入口点,负责以下核心任务:

flowchart TD A[HTTP Request] --> B[DispatcherServlet] B --> C{HandlerMapping} C --> D[Controller] D --> E[ModelAndView] E --> F{ViewResolver} F --> G[View] G --> H[HTTP Response]

配置 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. 渲染视图并返回响应

数学表示请求映射关系: f:RH where R is request,H is handler

核心组件交互[编辑 | 编辑源代码]

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没有内容。

模板:Tip

性能考量[编辑 | 编辑源代码]

  • 默认情况下,DispatcherServlet 是线程安全的
  • 避免在控制器中维护状态
  • 对于高并发场景,考虑:
 * 使用异步处理
 * 优化视图解析
 * 缓存静态资源

参见[编辑 | 编辑源代码]