SpringMVC
概念
Spring MVC
是基于前端控制器(Front Controller
)设计模式的 Web 框架,在 Web 应用中指一个统一的入口,用来接收所有客户端请求,并统一进行分发、处理。在 SpringMVC
中,前端控制器就是 DispatcherServlet
,它的作用包括:
- 接收所有请求
- 调用对应的处理器(
Controller
) - 统一处理返回结果(视图渲染、数据响应等)
整体工作流程
工作流程图
用户发起请求
用户在浏览器输入一个地址,例如
http://localhost:8080/api/seckill/execute
这个请求先被 Web 容器(Tomcat
)接收,再被转交给 Spring MVC
的核心组件——DispatcherServlet
。
DispatcherServlet
进行调度
DispatcherServlet
拿到请求之后会调用doDispatch()
,DispatcherServlet
接收到请求后会执行一系列方法,主要流程都集中的 doDispatch()
方法中
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 1. 获取 HandlerExecutionChain(处理器执行链)
mappedHandler = getHandler(processedRequest);
// 2. 获取 HandlerAdapter(处理器适配器)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 调用前置拦截器(可选)
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 4. 执行 Controller 处理方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 5. 调用后置拦截器(可选)
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
// 6. 处理视图渲染或异常
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
下面依次介绍
查找处理器(handler
)
// mappedHandler = getHandler(processedRequest);
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
遍历所有 HandlerMapping
,逐个尝试匹配请求,找到对应的处理器(Controller
)执行链
HandlerMapping
是一个接口,常见的实现类有RequestMappingHandlerMapping
处理基于注解的请求映射(如 @RequestMapping
、@GetMapping
等)
获取对应的处理器适配器(HandlerAdapter
)
// HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
}
遍历所有 HandlerAdapter
,判断当前适配器是否支持处理传入的 handler(Controller)
HandlerAdapter
的作用在于解耦 DispatcherServlet
与具体 Controller
实现,使得通过同一个接口来调用不同类型的处理器(Controller
)
调用 Controller
方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
返回一个 ModelAndView
对象。
实际上是以反射的方式获取Method
,再Method.invoke()
执行目标方法。
ModelAndView
是封装模型数据和视图信息的对象。
public class ModelAndView {
private Object view;
/** ModelMap继承了LinkedHashMap<String, Object>*/
private ModelMap model;
}
Model(模型):用于存放业务数据,类型是一个 LinkedHashMap<String, Object>
View(视图):视图名称或者视图对象(如 JSP),用来告诉框架最终渲染哪个页面
视图解析与渲染
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
->render(mv, request, response);
->View view;
->view = resolveViewName(viewName, mv.getModelInternal(), locale, request);//返回View对象
->view.render(mv.getModelInternal(), request, response);//渲染
根据mv
中的view
找到对应的ViewResolver
,ViewResolver
的作用是
Controller
返回的是一个逻辑视图名(例如"home"
)ViewResolver
会根据配置,把逻辑视图名转换成具体视图文件的路径(例如/WEB-INF/views/home.jsp
)- 视图解析后由视图渲染器渲染页面并返回给客户端,就是将
mv
中的model
数据填充到View
对象中