一、实现原理
Spring MVC是基于Servlet API构建的,并使用前端控制器模式。其核心是DispatcherServlet
,它负责接收HTTP请求、委派处理并返回响应。
Spring MVC 工作流程细化
当一个HTTP请求到达Spring MVC的DispatcherServlet时,以下是其详细的工作流程:
接收请求:DispatcherServlet
接收到客户端的请求。
解析请求:DispatcherServlet
将请求传递给HandlerMapping
,它返回一个处理请求的控制器。
处理请求:DispatcherServlet
将请求委派给由HandlerMapping
选择的控制器。控制器处理请求并返回ModelAndView
对象,该对象包含模型数据和逻辑视图名称。
解析视图:DispatcherServlet
将ModelAndView
对象传递给ViewResolver
,它返回一个具体的视图对象。
渲染视图:视图对象使用模型数据来渲染页面,并将渲染的页面作为响应返回给客户端。
返回响应:DispatcherServlet
返回响应给客户端。
这个工作流程确保了MVC的分离,使得控制器、模型和视图可以独立地开发和修改,而不会相互影响。
- 请求首先到达
DispatcherServlet
。 DispatcherServlet
查询一个或多个HandlerMapping
来确定请求应由哪个控制器处理。- 控制器处理请求并返回一个
ModelAndView
对象。 DispatcherServlet
查询一个或多个ViewResolver
来渲染视图。
二、核心知识点及源码分析
DispatcherServlet:前端控制器,负责处理所有请求。在DispatcherServlet.doDispatch()
方法中,它处理请求并委派给相应的控制器。
HandlerMapping:确定哪个控制器应处理请求。例如,RequestMappingHandlerMapping
查找带有@RequestMapping
注解的方法。
Controller:处理请求并返回ModelAndView
。在控制器方法中,可以直接返回ModelAndView
或使用@ResponseBody
返回JSON/XML响应。
ViewResolver:解析逻辑视图名称到具体的视图对象。例如,InternalResourceViewResolver
可以解析到JSP页面。
Model:包含视图所需的数据。它是一个Map结构,可以存储任何数据对象。
三、常见面试问题及回答
Q: Spring MVC和Struts有什么区别?
A: Spring MVC是Spring框架的一部分,提供了与Spring的其他部分(如安全性和事务管理)的集成。Struts是一个独立的MVC框架。两者的配置和API有所不同,但都遵循MVC模式。
Q: 如何在Spring MVC中处理异常?
A: 可以使用@ExceptionHandler
注解或实现HandlerExceptionResolver
。
Q: 什么是ModelAndView
?
A: 它是一个包含模型数据和视图名称的对象,控制器返回它来告诉DispatcherServlet
如何响应请求。
四、使用场景及代码
(1)Web应用程序:使用Spring MVC构建传统的服务器端渲染的应用程序。
@Controller
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ModelAndView getUser(@PathVariable Long id) {
User user = userService.findById(id);
ModelAndView mav = new ModelAndView("userDetail");
mav.addObject("user", user);
return mav;
}
}
(2)RESTful Web服务:使用@RestController
和@RequestMapping
构建REST API。
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
}