1、SpringMVC的体系架构及工作原理图
从接收请求到返回响应,SpringMVC的组件通力配合、各司其职、有条不紊的完成分内的工作。DispatcherServletc处于核心地位,负责协调各组件来完成处理请求和响应的工作。
2、SpringMVC处理请求的整体过程
1,客户端发出一个Http请求,Web应用服务器接收到这个请求,如果匹配
DispatcherServlet的请求映射路径,则会将请求转交DispatcherServlet来处理
2,DispatcherServlet的任务是将请求发送给一个Controller来处理,但是应用程序中可能 包含多个Controller,DispatcherServlet需要知道应该将请求发送给哪一个 Controller,DispatcherServlet会根据请求信息来查询一个或多个处理器映射器
(HandlerMapping)来确定请求的下一站在哪里
3,选择好合适的控制器后,会使用HandlerAdapter对Handler进行封装,
以统一的适配器接口来调用Handler
4,处理器完成业务逻辑之后返回ModelAndView对象给DispatcherServlet,ModelAndView不是真正的视图对象,只是包含视图逻辑名和数据信息
5,DispatcherServlet使用ViewResolver完成视图逻辑名到真正视图对象 的解析过程
6,得到View视图对象后,将ModelAndView中的数据渲染到View视图中
7,响应给客户端
3、架构图对应的DispatcherServlet核心源码
//前端控制器分派方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//检查是否为文件上传
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
/*为当前请求确定处理程序 Handler
2,DispatcherServlet会根据请求信息来查询一个或多个
处理器映射器(HandlerMapping)来确定请求的下一站在哪里
*/
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
/*为当前请求确定处理程序适配器。
3,使用HandlerAdapter对Handler进行封装,
以统一的适配器接口来调用Handler
*/
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
......
/*
4、实际调用处理程序(调用处理器的相应功能处理方法)
返回ModelAndView对象给DiapatcherServlet,
ModelAndView不是真正的视图对象,只是包含视图逻辑名和数据信息
*/
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
}
View view;
if (mv.isReference()) {
/*
5、DispatcherServlet使用ViewResolver完成视图逻辑名
到真正视图对象的解析过程
6,将ModelAndView中的数据渲染到View视图中
*/
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
}
}