Spring MVC 是 Spring 框架中的一个核心模块,用于构建基于 Java 的 Web 应用程序。它的实现原理基于经典的 MVC(Model-View-Controller)设计模式,并通过 前端控制器模式(DispatcherServlet
)统一处理请求,结合依赖注入和面向切面编程(AOP),提供灵活的请求处理机制。以下是 Spring MVC 的核心实现原理和工作流程:
一、核心组件与角色
-
DispatcherServlet
(前端控制器)- 核心入口:所有 HTTP 请求首先到达
DispatcherServlet
,由其统一调度。 - 职责:协调其他组件(如
HandlerMapping
、HandlerAdapter
、ViewResolver
)完成请求处理。
- 核心入口:所有 HTTP 请求首先到达
-
HandlerMapping
(处理器映射)- 作用:根据请求的 URL 和配置,找到对应的处理器(
Controller
或@Controller
注解的类)。 - 默认实现:
RequestMappingHandlerMapping
(基于@RequestMapping
注解)。
- 作用:根据请求的 URL 和配置,找到对应的处理器(
-
HandlerAdapter
(处理器适配器)- 作用:调用具体的处理器方法(如
@Controller
中的方法),处理请求参数绑定、返回值解析等。 - 默认实现:
RequestMappingHandlerAdapter
。
- 作用:调用具体的处理器方法(如
-
ViewResolver
(视图解析器)- 作用:将逻辑视图名(如
"home"
)解析为具体的视图对象(如 JSP、Thymeleaf 模板)。 - 常用实现:
InternalResourceViewResolver
(用于 JSP)。
- 作用:将逻辑视图名(如
-
HandlerExceptionResolver
(异常解析器)- 作用:统一处理请求处理过程中抛出的异常。
-
ModelAndView
- 数据与视图的容器:封装业务逻辑处理后的数据(Model)和视图名称(View)。
二、Spring MVC 请求处理流程
以下是 Spring MVC 处理 HTTP 请求的核心流程:
1. 请求到达 DispatcherServlet
- 所有请求首先由
DispatcherServlet
接收(在web.xml
或 Servlet 3.0+ 配置中映射为/
)。
2. 查找处理器(Handler)
HandlerMapping
根据请求的 URL、HTTP 方法等,找到对应的Controller
和方法(通过@RequestMapping
匹配)。
3. 执行处理器方法
HandlerAdapter
负责调用具体的处理器方法:- 参数绑定:自动将 HTTP 请求参数绑定到方法参数(如
@RequestParam
、@PathVariable
)。 - 返回值处理:根据方法返回类型(如
String
、ModelAndView
)决定下一步操作。
- 参数绑定:自动将 HTTP 请求参数绑定到方法参数(如
4. 处理业务逻辑
- 在
Controller
方法中执行业务逻辑(如调用 Service 层),并返回一个逻辑视图名或数据(如 JSON)。
5. 处理返回结果
- 如果返回
String
(视图名),ViewResolver
将其解析为具体的视图(如/WEB-INF/views/home.jsp
)。 - 如果返回
@ResponseBody
或 JSON 数据,直接通过HttpMessageConverter
序列化为响应内容。
6. 渲染视图
- 将 Model 中的数据填充到视图中(如 JSP 的
${user.name}
)。 - 生成最终的 HTTP 响应返回客户端。
流程图
Client → DispatcherServlet → HandlerMapping → HandlerAdapter → Controller → ModelAndView → ViewResolver → View → Client
三、关键实现细节
1. 注解驱动开发
@Controller
:标记一个类为控制器。@RequestMapping
:定义请求 URL 与处理方法的映射。@RequestParam
、@PathVariable
:绑定请求参数到方法参数。@ResponseBody
:将返回值直接写入响应体(如返回 JSON)。
2. 数据绑定与类型转换
- 通过
WebDataBinder
自动将请求参数绑定到对象(如将表单字段绑定到User
对象的属性)。 - 支持自定义类型转换器(如日期格式转换)。
3. 拦截器(Interceptor)
- 实现
HandlerInterceptor
接口,在请求处理前后插入逻辑(如权限验证、日志记录)。
4. 视图技术集成
- 支持多种视图技术(JSP、Thymeleaf、FreeMarker、JSON 等)。
- 通过
ViewResolver
和View
接口解耦视图实现。
5. RESTful 支持
- 通过
@RestController
(组合@Controller
+@ResponseBody
)简化 REST API 开发。 - 支持 HTTP 方法映射(
@GetMapping
、@PostMapping
等)。
四、配置方式
1. XML 配置(传统方式)
<!-- web.xml 中配置 DispatcherServlet -->
<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>
2. Java 配置(Servlet 3.0+)
public class WebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
// 创建 DispatcherServlet 并注册
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", servlet);
registration.addMapping("/");
}
}
3. Spring Boot 自动配置
- Spring Boot 通过
@EnableWebMvc
或自动配置(WebMvcAutoConfiguration
)简化配置。 - 默认使用嵌入式 Tomcat,无需手动部署。
五、与 Servlet 的关系
- 基于 Servlet API:Spring MVC 本质上是对 Servlet 的封装,
DispatcherServlet
继承自HttpServlet
。 - 扩展性:通过拦截器、过滤器(Filter)、AOP 等增强功能,但核心流程仍遵循 Servlet 规范。
六、总结
Spring MVC 的核心原理是通过 前端控制器模式(DispatcherServlet
)统一分发请求,结合 注解驱动 和 组件化设计,实现了以下优势:
- 解耦:分离控制器、业务逻辑、视图渲染。
- 灵活性:支持多种视图技术、数据格式(JSON/XML)、配置方式。
- 高效开发:通过注解减少样板代码。
- 易于测试:依赖注入(DI)使各组件可独立测试。
尽管现代开发中 Spring Boot 进一步简化了配置,但理解 Spring MVC 的原理仍是掌握 Java Web 开发的关键基础。