SpringMVC流程如下:
在SpringMVC整个工作流程中DispatcherServlet是其中的一个重点。因此通过源码的来简单分析Spring MVC的大体流程:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
...
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
...
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
...
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
...
}
1、当用户发起请求之后,DispatcherServlet会根据请求的信息(URL、请求头、请求参数、Cookie等)以及HandlerMapping的配置去匹配对应的Handler。以下为匹配过程中的部分源码:
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
...
HandlerExecutionChain handler = hm.getHandler(request);
...
}
@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
...
}
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
...
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
...
}
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<Match> matches = new ArrayList<Match>();
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
addMatchingMappings(directPathMatches, matches, request);
}
...
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
...
}
当匹配到对应的Handler之后,DispatcherServlet会将得到的Handler告知HandlerAdapter,HandlerAdapter再根据请求去定位请求的具体处理方法是哪一个。
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
Handler完成对用户请求的处理后,将返回一个ModelAndView对象给DispatcherServlet
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
此时ModelAndView的视图是逻辑视图,DispatcherServlet还要借助ViewResolver完成视图的解析。即逻辑视图解析为真实视图对象。
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
...
render(mv, request, response);
...
}
最后得到真正的视图对象后,DispatcherServlet利用视图对象对模型数据进行渲染。并将响应返回给用户。