Spring MVC 全面详解
Spring MVC 是 Spring 框架的一个模块,是 Java 主流的 Web 开发框架之一。它基于模型-视图-控制器(MVC)设计模式,提供了一种灵活、可扩展的方式来构建 Web 应用程序。Spring MVC 强调松耦合、易测试性和可配置性,广泛用于企业级 Web 开发,尤其在 RESTful API、单页应用(SPA)和传统 Web 页面渲染中。以下是对 Spring MVC 的全面详解,包括其原理、组件、工作流程、配置、示例和最佳实践。内容基于 Spring Framework 6.x 版本(截至 2026 年初的最新稳定版)。
1. Spring MVC 概述
- 定义:Spring MVC 是 Spring 框架的 Web 层实现,它处理 HTTP 请求,将请求映射到控制器方法,并渲染响应(如 HTML、JSON 或 XML)。它支持多种视图技术(如 JSP、Thymeleaf、Freemarker)和数据格式(如 JSON、XML)。
- 优势:
- 模块化:与 Spring Core、Spring Boot 等无缝集成。
- 灵活性:支持注解驱动开发,减少 XML 配置。
- 性能:内置缓存、异步处理(Servlet 3.0+ 支持)。
- 安全性:集成 Spring Security,支持 CSRF 防护、认证等。
- 测试友好:易于单元测试控制器和服务。
- 缺点:相比 Spring Boot,纯 Spring MVC 配置稍显繁琐;对于微服务,Spring WebFlux(响应式)可能更适合。
- 适用场景:企业 Web 应用、API 服务、电商平台等。相比其他框架(如 Struts、JSF),Spring MVC 更现代化、更活跃。
2. 历史与发展
- 起源:2003 年随 Spring 框架发布,早起基于 Servlet API。
- 关键版本:
- Spring 3.0(2010):引入注解(如
@Controller、@RequestMapping),减少 XML。 - Spring 4.0(2013):支持 WebSocket、REST 改进。
- Spring 5.0(2017):响应式编程集成,支持 Java 8+。
- Spring 6.0(2022):原生支持 Java 17+,增强 AOT(Ahead-of-Time)编译。
- 截至 2026 年:Spring 6.1+ 版本优化了 GraalVM 支持,适用于云原生应用。
- 当前状态:Spring MVC 仍是主流,但 Spring Boot 简化了其使用,许多项目迁移到 Boot。
3. 核心组件
Spring MVC 的核心是基于 DispatcherServlet 的前端控制器模式。以下是主要组件:
| 组件名称 | 描述 | 关键接口/类 |
|---|---|---|
| DispatcherServlet | 中央调度器,接收所有 HTTP 请求,分发到处理器。初始化时加载 Spring 配置。 | org.springframework.web.servlet.DispatcherServlet |
| HandlerMapping | 映射请求 URL 到控制器方法。默认使用 RequestMappingHandlerMapping。 | HandlerMapping 接口,支持注解映射。 |
| Controller | 处理业务逻辑,返回 ModelAndView 或响应体。 | 用 @Controller 或 @RestController 注解的类。 |
| HandlerAdapter | 适配器,调用控制器方法。默认 RequestMappingHandlerAdapter。 | 支持方法参数解析(如 @PathVariable)。 |
| ViewResolver | 解析逻辑视图名到实际视图(如 JSP)。 | InternalResourceViewResolver 或 ThymeleafViewResolver。 |
| ModelAndView | 封装模型数据和视图名。 | 用于传统 MVC,返回给视图渲染。 |
| ExceptionHandler | 处理异常。 | @ExceptionHandler 注解在控制器中。 |
| Interceptor | 拦截器,类似 AOP,用于日志、认证等。 | HandlerInterceptor 接口。 |
其他辅助组件:MultipartResolver(文件上传)、LocaleResolver(国际化)、ThemeResolver(主题)。
4. 工作流程
Spring MVC 处理一个 HTTP 请求的典型流程:
- 请求到达:客户端发送 HTTP 请求到 Tomcat/Jetty 等 Servlet 容器。
- DispatcherServlet 接收:作为前端控制器,拦截请求(web.xml 或 Java 配置中映射到
/或*.do)。 - HandlerMapping 映射:根据 URL、HTTP 方法(GET/POST)等,找到匹配的控制器方法。
- HandlerAdapter 执行:调用控制器方法,解析参数(@RequestParam、@PathVariable 等),执行业务逻辑。
- 返回结果:控制器返回 ModelAndView、String(视图名)、ResponseEntity 或直接对象(JSON)。
- ViewResolver 解析:如果返回视图名,解析成实际视图(如 JSP),渲染模型数据。
- 响应客户端:返回 HTML、JSON 等。如果异常,交给 ExceptionResolver 处理。
- 拦截器介入:preHandle(前)、postHandle(后)、afterCompletion(完成)。
流程图(文本表示):
客户端请求 → DispatcherServlet → HandlerMapping → Controller → 业务逻辑 → ModelAndView → ViewResolver → 视图渲染 → 响应
异步支持:使用 @Async 或 Callable 返回值,实现非阻塞。
5. 配置方式
Spring MVC 支持 XML 和 Java 配置。现代项目偏好注解 + Java 配置。
- XML 配置(传统,web.xml):
<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.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在 spring-mvc.xml 中配置组件扫描、视图解析等。
- Java 配置(推荐,无 web.xml,使用 Servlet 3.0+):
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.example.controller")
public class WebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
// 添加拦截器、CORS 等
}
初始化:扩展 AbstractAnnotationConfigDispatcherServletInitializer。
与 Spring Boot 集成:Boot 自动配置 DispatcherServlet,使用 @SpringBootApplication 即可。
6. 常用注解
Spring MVC 重度依赖注解驱动开发:
| 注解 | 描述 | 示例 |
|---|---|---|
@Controller | 标记控制器类。 | @Controller public class UserController {} |
@RestController | @Controller + @ResponseBody,用于 REST API,返回 JSON。 | @RestController @RequestMapping("/api") |
@RequestMapping | 映射 URL、方法(GET/POST)。支持 @GetMapping、@PostMapping 等快捷。 | @GetMapping("/users/{id}") |
@PathVariable | 提取 URL 参数。 | public User getUser(@PathVariable Long id) |
@RequestParam | 提取查询参数。 | public List<User> search(@RequestParam String name) |
@RequestBody | 解析请求体(如 JSON)。 | public void create(@RequestBody User user) |
@ResponseBody | 返回对象直接序列化为响应体。 | 方法上注解。 |
@ExceptionHandler | 处理特定异常。 | @ExceptionHandler(RuntimeException.class) |
@ModelAttribute | 绑定表单数据到对象。 | 方法参数或方法上。 |
@Valid | 验证 Bean(如 JSR-303)。 | 与 @RequestBody 结合。 |
7. 示例代码
一个简单的 CRUD 示例(用户管理)。
- 控制器:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
@PostMapping
public User createUser(@RequestBody @Valid User user) {
return userService.save(user);
}
@ExceptionHandler(ValidationException.class)
public ResponseEntity<String> handleValidation(Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
- 服务层(UserService):注入 Repository,使用 Spring Data JPA。
- 视图(如果非 REST):返回 “userList”,ViewResolver 解析到 /WEB-INF/views/userList.jsp。
文件上传示例:
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
// file.transferTo(new File("/path"));
return "success";
}
8. 最佳实践
- RESTful 设计:使用 HTTP 方法和状态码正确(如 200 OK、404 Not Found)。
- 安全性:集成 Spring Security,使用
@PreAuthorize控制访问。 - 性能优化:启用缓存(@Cacheable)、压缩响应、异步处理。
- 测试:使用 MockMvc 测试控制器:
MockMvcBuilders.webAppContextSetup(context).build()。 - 错误处理:全局
@ControllerAdvice处理异常。 - 国际化:使用 MessageSource 和 LocaleResolver。
- 与前端集成:支持 CORS(@CrossOrigin)、JSON(Jackson)。
- 迁移建议:新项目用 Spring Boot + MVC;旧项目渐进式重构。
- 常见问题:404(映射错误)、415(媒体类型不支持)——检查注解和依赖。
9. 高级主题
- 与 Spring Boot:Boot 提供 starters 如
spring-boot-starter-web,自动配置。 - 响应式:Spring WebFlux 替代 MVC,用于高并发。
- GraphQL:集成 Spring GraphQL。
- 微服务:结合 Spring Cloud。
- 工具:Maven/Gradle 依赖
spring-webmvc;IDE 如 IntelliJ 支持注解导航。
如果需要特定版本细节、代码调试或扩展示例(如整合数据库),请提供更多信息!