Spring MVC 中的组件与 MVC 角色的对应:
-
Controller (控制器):
- 体现: 主要由我们开发时编写的带有
@Controller
或@RestController
注解的 Java 类及其内部的方法(通常称为 Handler 方法)来体现。 - 职责:
- 接收请求: 通过
@RequestMapping
及其变体 (@GetMapping
,@PostMapping
等) 注解,将特定的 HTTP 请求(URL、HTTP 方法、参数等)映射到对应的 Handler 方法。DispatcherServlet
会根据HandlerMapping
的结果找到这个 Controller 方法。 - 处理用户输入: 解析请求中的数据,如查询参数 (
@RequestParam
)、路径变量 (@PathVariable
)、请求体 (@RequestBody
)、表单数据等,并将它们绑定到方法的参数上。 - 调用业务逻辑 (与 Model 交互): 调用注入的 Service 层或其他业务逻辑组件来执行实际的业务操作、数据处理或数据获取。
- 准备模型数据: 将处理结果或需要展示的数据(即 Model 数据)封装起来,以便传递给 View。这通常通过向方法参数中的
Model
对象添加属性,或者构建并返回一个ModelAndView
对象来实现。 - 选择视图: 返回一个逻辑视图名(String 类型),或者返回一个包含逻辑视图名和模型数据的
ModelAndView
对象。对于 RESTful 服务 (@RestController
或方法上使用@ResponseBody
),Controller 直接返回需要序列化的对象(如 POJO),此时响应体本身扮演了视图的角色。
- 接收请求: 通过
- 体现: 主要由我们开发时编写的带有
-
Model (模型):
- 体现: 在 Spring MVC 中,Model 的体现是多方面的:
- 数据载体 (Data Carrier): 最直接的体现是 Controller 传递给 View 的数据。Spring MVC 提供了
Model
接口(及其实现如ModelMap
)或ModelAndView
类来充当这个数据容器。我门将需要展示的数据放入这些容器中。 - 业务状态与逻辑 (Business State & Logic): 更深层次上,Model 代表了应用程序的核心。这通常是 Controller 调用的 Service 层和 Repository/DAO 层 Bean。这些 Bean 封装了业务规则、数据持久化逻辑以及应用程序的状态。Controller 与这些 Bean 交互来读取或修改应用状态。
- 领域对象 (Domain Objects): Controller 处理或传递的普通 Java 对象(POJO),如
User
,Product
,Order
等,它们代表了业务领域中的实体。
- 数据载体 (Data Carrier): 最直接的体现是 Controller 传递给 View 的数据。Spring MVC 提供了
- 职责:
- 封装数据: 持有需要传递给视图的数据(通过
Model
或ModelAndView
)。 - 执行业务逻辑: Service/Repository 层负责处理业务规则、数据验证、与数据库交互等核心任务。
- 维护应用状态: 代表了应用程序当前的数据状态。
- 封装数据: 持有需要传递给视图的数据(通过
- 体现: 在 Spring MVC 中,Model 的体现是多方面的:
-
View (视图):
- 体现:
- 视图模板: 各种模板引擎的文件,如 JSP 文件、Thymeleaf 模板 (
.html
)、Freemarker 模板 (.ftl
) 等。 - Spring 的
View
接口: Spring MVC 定义了一个View
接口,以及针对不同视图技术的具体实现(如JstlView
,ThymeleafView
)。ViewResolver
负责将逻辑视图名解析为具体的View
实例。 - 直接响应内容: 对于 RESTful 服务,由
HttpMessageConverter
(如 Jackson 处理 JSON)将 Controller 返回的对象序列化后的内容(JSON, XML 等)也可以看作是一种特殊的视图。
- 视图模板: 各种模板引擎的文件,如 JSP 文件、Thymeleaf 模板 (
- 职责:
- 呈现数据: 获取 Controller 传递过来的模型数据(从
Model
或ModelAndView
中提取)。 - 渲染用户界面: 使用模型数据填充视图模板,生成最终的 HTML、JSON、XML 或其他格式的响应内容,呈现给用户。
- 不包含业务逻辑: 视图应该尽量保持简单,只负责展示逻辑。
- 呈现数据: 获取 Controller 传递过来的模型数据(从
- 体现:
它们之间的协作流程 (由 DispatcherServlet
驱动):
- 请求入口: HTTP 请求到达
DispatcherServlet
。 - 寻找处理器:
DispatcherServlet
查询HandlerMapping
,根据请求信息(URL, HTTP Method 等)找到能够处理该请求的 Controller 方法 (Handler)。 - 适配与调用:
DispatcherServlet
通过HandlerAdapter
来调用选定的 Controller 方法。HandlerAdapter
负责处理方法参数的解析和数据绑定(例如,将请求参数注入到@RequestParam
标记的参数,将 JSON 请求体反序列化到@RequestBody
标记的对象)。 - Controller 处理: Controller 方法执行:
- 接收解析后的请求数据。
- 调用 Service 层等(与 Model 交互)执行业务逻辑。
- 将结果数据放入
Model
对象(或ModelAndView
)。 - 返回逻辑视图名(String)或
ModelAndView
对象(或直接返回数据对象给@ResponseBody
)。
- 视图解析 (非
@ResponseBody
): 如果 Controller 返回的是逻辑视图名或ModelAndView
,DispatcherServlet
会将逻辑视图名交给ViewResolver
。 - 获取具体视图:
ViewResolver
根据逻辑视图名解析得到具体的View
实例(例如,一个指向特定 JSP 文件的JstlView
对象)。 - 数据渲染:
DispatcherServlet
将 Controller 准备好的Model
数据传递给View
实例。View
实例使用这些数据渲染最终的响应(例如,JSP 引擎执行 JSP 文件并生成 HTML)。 - REST 响应 (
@ResponseBody
): 如果 Controller 方法使用了@ResponseBody
或属于@RestController
,HandlerAdapter
会使用合适的HttpMessageConverter
将返回的对象序列化为特定格式(如 JSON)并直接写入响应体。此过程通常跳过视图解析和View
渲染步骤。 - 响应返回:
DispatcherServlet
将最终生成的响应(渲染后的 HTML 或序列化后的数据)返回给客户端。
通过这种方式,Spring MVC 利用 DispatcherServlet
作为前端控制器,协调 HandlerMapping
, HandlerAdapter
, Controller
, Model
, ViewResolver
, View
等组件,清晰的实现了 MVC 模式的功能分离,使得我们在开发时可以专注于各自的部分,构建出易于维护的 Web 应用程序。