天门市网站建设_网站建设公司_Java_seo优化
2026/1/21 16:20:27 网站建设 项目流程

Spring 核心 —— Spring MVC

1. 核心理论:什么是 Spring MVC?

Spring MVC 是 Spring Framework 提供的一个用于构建 Web 应用程序的模块。它基于 MVC (Model-View-Controller, 模型-视图-控制器) 设计模式,将 Web 应用的各个部分解耦,提高了代码的可维护性和可扩展性。

  • MVC 设计模式:

    • Model (模型): 应用程序的数据和业务逻辑。通常是 POJO (Plain Old Java Object, 简单无侵入 Java 对象)。
    • View (视图): 用于渲染 Model 数据,向用户展示界面。例如 JSP, Thymeleaf, JSON 等。
    • Controller (控制器): 接收用户请求,调用业务逻辑处理,并返回 Model 和 View。
  • 核心思想: Spring MVC 的核心是一个前端控制器 (Front Controller),即 DispatcherServlet(前端控制器)。所有的请求都会先经过 DispatcherServlet(前端控制器),然后由它统一分发给不同的处理器进行处理。


2. 深度剖析:Spring MVC 的核心流程

下图清晰地展示了 Spring MVC 的完整工作流程:

+------------+   1. 发送请求   +-----------------------+
|  Client    | ------------> |  DispatcherServlet    |
| (浏览器)    |               |    (前端控制器)       |
+------------+               +-----------+-----------+|| 2. 查询处理器v+-----------------------+|    HandlerMapping     ||   (处理器映射器)      |+-----------------------+|+-------------------------------+ 3. 返回 HandlerExecutionChain|                                         (包含 Handler 和 Interceptors)v
+--------+----------+
|  DispatcherServlet |
+--------+----------+|| 4. 请求 HandlerAdapter 执行 Handlerv
+-----------------------+      +--------------------------+
|    HandlerAdapter     | ---> |  Handler (Controller)    |
|    (处理器适配器)     |      |       (你的代码)         |
+-----------------------+      +------------+-------------+|+--------------------------------+ 5. Controller 返回 ModelAndView|v
+--------+----------+
|  DispatcherServlet |
+--------+----------+|| 6. 请求 ViewResolver 解析视图v
+-----------------------+
|     ViewResolver      |
|     (视图解析器)      |
+-----------------------+|+-------------------------------+ 7. 返回具体的 View|v
+--------+----------+
|  DispatcherServlet |
+--------+----------+|| 8. 渲染视图 (将 Model 数据填充到 View)v
+-----------------------+      +----------------+
|         View          | ---> |     Model      |
|        (视图)         |      |     (数据)     |
+-----------------------+      +----------------+|+-------------------------------+ 9. 返回响应|v
+------------+
|   Client   |
+------------+

当一个 HTTP 请求到达时,Spring MVC 的处理流程如下:

  1. 请求到达 DispatcherServlet(前端控制器): 所有的请求首先由前端控制器 DispatcherServlet接收。
  2. DispatcherServlet(前端控制器) 查询 HandlerMapping(处理器映射器): DispatcherServlet(前端控制器) 会调用 HandlerMapping (处理器映射器),请求它根据请求的 URL 找到对应的处理器(即 Controller(控制器) 的方法)。HandlerMapping(处理器映射器) 会返回一个 HandlerExecutionChain(处理器执行链) 对象。
    • HandlerExecutionChain (处理器执行链): 这是一个重要的内部对象,它不仅仅包含了找到的处理器(Handler),还包含了所有匹配该请求的拦截器 (HandlerInterceptor)。这就像一条流水线,请求在到达真正的处理器之前,需要先经过一系列的拦截器(如权限检查、日志记录等)。
  3. 执行处理器: DispatcherServlet(前端控制器) 会根据 HandlerAdapter (处理器适配器),先按顺序执行 HandlerExecutionChain(处理器执行链) 中的拦截器的 preHandle 方法,然后再调用相应的处理器方法。
  4. 处理器返回 ModelAndView(模型与视图): Controller(控制器) 方法执行完毕后,会返回一个 ModelAndView(模型与视图) 对象,其中包含了数据模型(Model)和逻辑视图名(View Name)。
  5. DispatcherServlet(前端控制器) 请求 ViewResolver(视图解析器): DispatcherServlet(前端控制器) 将 ModelAndView(模型与视图) 中的逻辑视图名传递给 ViewResolver(视图解析器)。
  6. ViewResolver(视图解析器) 返回 View(视图): ViewResolver(视图解析器) 解析逻辑视图名,并返回一个具体的 View(视图) 对象(如 JspView, ThymeleafView 等)。
  7. DispatcherServlet(前端控制器) 渲染视图: DispatcherServlet(前端控制器) 调用 View(视图) 对象的 render() 方法,将 Model 数据填充到视图中。
  8. 返回响应: DispatcherServlet(前端控制器) 将渲染后的视图作为 HTTP 响应返回给客户端。
  • 生活比喻: 想象你去一家大型医院看病
    • 你 (用户): 发起一个“看病”的请求。
    • DispatcherServlet (总服务台/导诊台): 你首先会去总服务台,而不是直接闯进某个科室。总服务台会接收你所有的请求。
    • HandlerMapping (分诊系统): 总服务台会根据你的“病症”(请求的 URL),查询分诊系统,告诉你应该去哪个科室找哪个医生(找到对应的 Controller 方法)。
    • Controller (医生): 你找到对应的医生,医生为你进行诊断(处理业务逻辑),并开出药方(返回 ModelAndView(模型与视图))。
    • ModelAndView (药方): 药方上写着你需要的数据(Model)和需要做的检查项目(View 的名称)。
    • ViewResolver (计价/导航系统): 你拿着药方去计价处,计价处会根据药方上的项目名称,告诉你具体要去哪个窗口缴费、哪个窗口取药(解析视图名称,找到具体的 View 实现)。
    • View (药房/检查科室): 你最终在药房取到了药,或者在检查科室完成了检查(渲染视图,生成最终的 HTML 或 JSON 响应)。

3. 核心组件与常用注解

3.1 核心组件详解

  • DispatcherServlet (前端控制器): 是整个 Spring MVC 的心脏和大脑,负责请求的统一分发和协调。
  • HandlerMapping (处理器映射器): 负责根据请求信息(如 URL)找到对应的处理器(Handler)。
  • HandlerAdapter (处理器适配器): 负责以一种统一的方式调用不同类型的处理器。
  • Controller (控制器): 处理器,负责处理用户请求,并返回 ModelAndView
  • ModelAndView (模型与视图): 模型和视图的容器,用于在 ControllerView 之间传递数据。
  • ViewResolver (视图解析器): 负责将逻辑视图名解析为具体的 View 对象。
  • View (视图): 负责渲染模型数据,生成最终的响应内容。

3.2 常用注解详解

  • @Controller / @RestController:

    • @Controller: 标记一个类为 Web 控制器,其方法的返回值通常是一个字符串,代表一个逻辑视图名 (View Name)。Spring MVC 会根据这个名字,找到对应的模板(如 JSP),然后将 Model 数据渲染成 HTML 页面返回给浏览器。
    • @RestController: 专门用于构建 RESTful Web 服务。它是一个组合注解,相当于 @Controller + @ResponseBody。它告诉 Spring,该控制器所有方法的返回值都应该被直接序列化(通常是转为 JSON),并作为 HTTP 响应的正文返回。
  • @RequestMapping / @GetMapping / @PostMapping:

    • @RequestMapping: 将 HTTP 请求映射到 Controller 的处理方法上,可以指定 URL、请求方法等。
    • @GetMapping: @RequestMapping(method = RequestMethod.GET) 的简写。
    • @PostMapping: @RequestMapping(method = RequestMethod.POST) 的简写。
  • @RequestParam / @PathVariable / @RequestBody:

    • @RequestParam: 用于获取 URL 中的查询参数(如 ?name=value)。
    • @PathVariable: 用于获取 URL 路径中的模板变量(如 /users/{id} 中的 id)。
    • @RequestBody: 用于将 HTTP 请求的 body 内容(通常是 JSON 或 XML)绑定到方法的参数上。
  • @ModelAttribute / @ResponseBody:

    • @ModelAttribute: 将方法的返回值或参数添加到 Model 中。
    • @ResponseBody: 标记在方法上,表示该方法的返回值直接作为 HTTP 响应的 body 内容返回,而不是解析为视图。

3.3 Spring MVC 中的父子容器 (Parent-Child Containers)

在一个典型的 Spring MVC Web 应用中,通常会存在两个 Spring 容器,它们构成了父子容器的关系。

  1. 父容器 (Parent Container / Root WebApplicationContext)

    • 创建者:通常由 ContextLoaderListener (在 web.xml 中配置) 创建。
    • 职责:负责管理业务层数据访问层的 Bean,例如 Service, Repository/DAO, DataSource, TransactionManager 等。这些是整个应用程序共享的、与 Web 层无关的 Bean。
  2. 子容器 (Child Container / Servlet WebApplicationContext)

    • 创建者:由 DispatcherServlet 创建。
    • 职责:负责管理Web 层的 Bean,例如 @Controller, ViewResolver, HandlerMapping, HandlerAdapter 等。这些 Bean 只与特定的 DispatcherServlet 相关。

父子容器的特点与优势:

  • 可见性规则
    • 子容器可以访问父容器中的 Bean:这意味着在 Controller (子容器中) 可以通过 @Autowired 注入 Service (父容器中)。
    • 父容器不能访问子容器中的 BeanService (父容器中) 不能注入 Controller (子容器中)。
  • 实现分层与解耦:这种结构清晰地将 Web 层与业务逻辑层分离开来,实现了关注点分离,使得系统架构更清晰。
  • 共享与隔离:多个 DispatcherServlet 可以共享同一个父容器中的业务 Bean,但每个 DispatcherServlet 又可以有自己独立的 Web 层配置,互不干扰。

4. 代码示例:创建一个简单的 Spring MVC 应用

我们将创建一个简单的 Web 应用,用于显示“Hello, Spring MVC!”。

4.1 Web 项目配置

要运行 Spring MVC,我们需要一个 Web 容器(如 Tomcat)和一个 web.xml 文件来配置 DispatcherServlet(前端控制器)

pom.xml (添加 Web 依赖)

<!-- ... 其他依赖 ... -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope>
</dependency>

web.xml (配置 DispatcherServlet)

<web-app ...><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></init-param><init-param><param-name>contextConfigLocation</param-name><param-value>com.study.spring.mvc.AppConfig</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>

4.2 Spring 配置与代码

// AppConfig.java (Spring 配置类)
package com.study.spring.mvc;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration
@EnableWebMvc // 启用 Spring MVC
@ComponentScan("com.study.spring.mvc")
public class AppConfig {// 配置视图解析器 (ViewResolver)@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/");resolver.setSuffix(".jsp");return resolver;}
}// HelloController.java (控制器)
package com.study.spring.mvc;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;@Controller
public class HelloController {@RequestMapping("/hello")public String sayHello(@RequestParam(value = "name", defaultValue = "World") String name, Model model) {// 1. 准备 Model 数据model.addAttribute("message", "Hello, " + name + "!");// 2. 返回逻辑视图名return "hello";}
}

4.3 视图 (JSP)

/WEB-INF/views/hello.jsp

<html>
<body><h2>${message}</h2>
</body>
</html>
  • 运行流程: 当用户访问 /hello?name=Spring 时,DispatcherServlet 会找到 HelloControllersayHello 方法。该方法将 message 属性添加到 Model 中,并返回逻辑视图名 helloViewResolverhello 解析为 /WEB-INF/views/hello.jsp,然后 Spring 将 Model 中的 message 数据渲染到 JSP 页面中,最终生成 HTML 响应。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询