spring mvc核心原始碼分析
前言
自研究了spring security核心原始碼以來,在實踐使用的基礎上更為深入的學習了它的思想.我的java世界彷彿被打開了一扇大門,開始對研究原始碼有種渴望.打算先看一輪核心原始碼,滿足目前工作需要,待對boot有個整體的瞭解之後再逐個細細研究
spring mvc核心流程圖
流程說明:
- 使用者傳送請求到dispatcherServlet,它執行父類frameworkServlet的service方法,service()->processRequest()開始處理請求,processRequest()->doService()->doDispatch();這一段都是給request里加入一些spring的bean,然後處理一下request
- dispatcherServlet遍歷自己的handlerMapping,當正確的handlerMapping找到handlerExcutionChain的時候返回,給dispatchServlet.(chain裡主要是一個handlerAdapter和一些攔截器)
- handlerExcutionChain開始攔截器處理請求,然後呼叫handlerAdapter裡的handler()方法,handler()->AbstractHandlerMethodAdapter裡的handleInternal(),然後反射執行我們controller裡的業務邏輯,將得到的modelAndView物件返回給dispatchServlet,然後繼續執行攔截器方法.
- dispacherServlet 呼叫processDispatchResult把得到的modelAndView交給viewResolve去render檢視
原始碼一覽
-
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
HttpServletRequest processedRequest = request;
-
HandlerExecutionChain mappedHandler = null;
-
boolean multipartRequestParsed = false;
-
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
-
try {
-
try {
-
ModelAndView mv = null;
-
Object dispatchException = null;
-
try {
-
//是否檔案上傳
-
processedRequest = this.checkMultipart(request);
-
multipartRequestParsed = processedRequest != request;
-
//獲取handlerExcutionChain
-
mappedHandler = this.getHandler(processedRequest);
-
if (mappedHandler == null) {
-
this.noHandlerFound(processedRequest, response);
-
return;
-
}
-
//獲取handlerAdapter
-
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
-
String method = request.getMethod();
-
boolean isGet = "GET".equals(method);
-
if (isGet || "HEAD".equals(method)) {
-
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
-
if (this.logger.isDebugEnabled()) {
-
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
-
}
-
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
-
return;
-
}
-
}
-
//呼叫攔截器們的前置方法
-
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
-
return;
-
}
-
//呼叫controller裡的業務邏輯方法並返回modelAndView
-
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
-
if (asyncManager.isConcurrentHandlingStarted()) {
-
return;
-
}
-
this.applyDefaultViewName(processedRequest, mv);
-
//呼叫攔截器的後置方法
-
mappedHandler.applyPostHandle(processedRequest, response, mv);
-
} catch (Exception var20) {
-
dispatchException = var20;
-
} catch (Throwable var21) {
-
dispatchException = new NestedServletException("Handler dispatch failed", var21);
-
}
-
//把modelAndView交給viewResolver去render檢視
-
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
-
} catch (Exception var22) {
-
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
-
} catch (Throwable var23) {
-
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
-
}
-
} finally {
-
if (asyncManager.isConcurrentHandlingStarted()) {
-
if (mappedHandler != null) {
-
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
-
}
-
} else if (multipartRequestParsed) {
-
this.cleanupMultipart(processedRequest);
-
}
-
}
-
}
-
獲取handlerExcutionChain物件
-
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
-
if (this.handlerMappings != null) {
-
Iterator var2 = this.handlerMappings.iterator();
-
while(var2.hasNext()) {
-
HandlerMapping hm = (HandlerMapping)var2.next();
-
if (this.logger.isTraceEnabled()) {
-
this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" + this.getServletName() + "'");
-
}
-
HandlerExecutionChain handler = hm.getHandler(request);
-
if (handler != null) {
-
return handler;
-
}
-
}
-
}
呼叫攔截器的前置方法
-
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
-
HandlerInterceptor[] interceptors = this.getInterceptors();
-
if (!ObjectUtils.isEmpty(interceptors)) {
-
for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
-
HandlerInterceptor interceptor = interceptors[i];
-
if (!interceptor.preHandle(request, response, this.handler)) {
-
this.triggerAfterCompletion(request, response, (Exception)null);
-
return false;
-
}
-
}
-
}
-
return true;
-
}
//攔截器的後置方法
-
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
-
HandlerInterceptor[] interceptors = this.getInterceptors();
-
if (!ObjectUtils.isEmpty(interceptors)) {
-
for(int i = interceptors.length - 1; i >= 0; --i) {
-
HandlerInterceptor interceptor = interceptors[i];
-
interceptor.postHandle(request, response, this.handler, mv);
-
}
-
}
-
}
反射controller我們寫的邏輯
-
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
-
this.checkRequest(request);
-
ModelAndView mav;
-
if (this.synchronizeOnSession) {
-
HttpSession session = request.getSession(false);
-
if (session != null) {
-
Object mutex = WebUtils.getSessionMutex(session);
-
synchronized(mutex) {
-
mav = this.invokeHandlerMethod(request, response, handlerMethod);
-
}
-
} else {
-
mav = this.invokeHandlerMethod(request, response, handlerMethod);
-
}
-
} else {
-
mav = this.invokeHandlerMethod(request, response, handlerMethod);
-
}
-
if (!response.containsHeader("Cache-Control")) {
-
if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
-
this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
-
} else {
-
this.prepareResponse(response);
-
}
-
}
-
return mav;
-
}
檢視渲染
-
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
-
boolean errorView = false;
-
if (exception != null) {
-
if (exception instanceof ModelAndViewDefiningException) {
-
this.logger.debug("ModelAndViewDefiningException encountered", exception);
-
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
-
} else {
-
Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
-
mv = this.processHandlerException(request, response, handler, exception);
-
errorView = mv != null;
-
}
-
}
-
if (mv != null && !mv.wasCleared()) {
-
this.render(mv, request, response);
-
if (errorView) {
-
WebUtils.clearErrorRequestAttributes(request);
-
}
-
} else if (this.logger.isDebugEnabled()) {
-
this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");
-
}
-
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
-
if (mappedHandler != null) {
-
mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
-
}
-
}
-
}
總結
springmvc核心並不複雜,主要是圍繞dispatcherServlet,請朋友們自動動手debugger,這樣學習才會更有效