寫過(guò)java后端的好像沒有不會(huì)spring mvc的漆际,至于spring mvc的介紹優(yōu)點(diǎn)河泳,自行g(shù)oogle腾誉,在這里就不balabala的介紹了。
在分析spring mvc源碼之前呵俏,先看一張圖:
請(qǐng)求處理的過(guò)程:
1.DispatcherServelt作為前端控制器,攔截request對(duì)象春瞬。
2.DispatcherServlet接收到request對(duì)象之后柴信,查詢HandlerMapping,得到一個(gè)HandlerExecutionChain對(duì)象。
3.DispatcherServlet將Handler對(duì)象交由HandlerAdapter(適配器模式的典型應(yīng)用)宽气,調(diào)用相應(yīng)的controller方法随常。
4.Controller方法返回ModelAndView對(duì)象,DispatcherServlet將view交由ViewResolver進(jìn)行解析萄涯,得到相應(yīng)的視圖绪氛。用model渲染視圖。
5.返回響應(yīng)結(jié)果涝影。
整個(gè)過(guò)程的流程其實(shí)就是DispatcherServelt中doDispatch()方法的調(diào)用過(guò)程枣察。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//第一步攔截request對(duì)象,doDispatch()方法在doService()方法中被調(diào)用燃逻,request對(duì)象是經(jīng)過(guò)處理的序目。
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//和文件的上傳和下載有關(guān)系,判斷請(qǐng)求的類型是否是multipart類型
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// Determine handler for the current request.
//主要看這里伯襟,這里是得到HandlerExecutionChain的方法猿涨。關(guān)于Handler()方法向下看
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
//這里已經(jīng)獲取到HandlerExecutionChain對(duì)象,接下來(lái)就要獲取HandlerAdapter對(duì)象姆怪,調(diào)用Handler對(duì)象的方法叛赚。
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler
//有關(guān)瀏覽器緩存的設(shè)定(304)
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//pan'du
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//解析視圖,數(shù)據(jù)渲染
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//遍歷HandlerMappingList對(duì)象(存儲(chǔ)若干個(gè)HandlerMapping對(duì)象)稽揭,不斷調(diào)用俺附,直到不為空為止,否則返回null
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}