SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter處理器適配器底層
先放一張圖
很熟悉啊,之前就看過,我們之前已經把handlerMapping剖了個底朝天,順著上次的進度,繼續跟,把HandlerAdapter處理器適配器剖一下
它同樣是由中央調度器DispatcherServlet調度到的,所以,還是這個類中找doDispatch(request,response)這個方法,我把有用的代碼,扒下來
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 err = null; Exception dispatchException= null; try { processedRequest = this.checkMultipart(request); multipartRequestParsed = processedRequest != request; mappedHandler = this.getHandler(processedRequest); if(mappedHandler == null || mappedHandler.getHandler() == null) { this.noHandlerFound(processedRequest, response); return; } //上面的是我說的HandleMapping的執行 流程 //所以從後面的第一行開始看 HandlerAdapter ex = this.getHandlerAdapter(mappedHandler.getHandler());
HandlerExecutionChain mappedHandler這個變量,是處理器執行鏈,它的getHandler方法,就是獲取它裏面的處理器
它外面的this.getHandlerAdpter
點過去追蹤
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { //叠代器 Iterator var2 = this.handlerAdapters.iterator(); //一會要返回去的適配器對象 HandlerAdapter ha; do { //如果沒有下一個的話。就拋異常 if(!var2.hasNext()) { throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); } //將此強轉成為處理器適配器 ha = (HandlerAdapter)var2.next(); if(this.logger.isTraceEnabled()) { this.logger.trace("Testing handler adapter [" + ha + "]"); } } while(!ha.supports(handler)); //這兒有個適配器模式 return ha; }
這是下載源碼後的最直觀的源碼
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
看ha.sipports(handler)這個方法
找到HandlerAdapter接口
public interface HandlerAdapter { boolean supports(Object handler); ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler); }
再來看一下自己寫的控制器實現了Controller。這樣就看DispatcherServlet屬性中的HandlerApater誰支持Controller類型的處理器了。在運行的過程中發現SimpleControllerHandlerAdapter是支持Controller類型的控制器的。
來看一下SimpleControllerHandlerAdapter的代碼
找它的實現類:Ctrl+H SimpleControllerHandlerAdapter
public class SimpleControllerHandlerAdapter implements HandlerAdapter { public boolean supports(Object handler) { return (handler instanceof Controller); } public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); } public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
它support來判斷是否是處理器
拿到處理器在中央調度器一處調用了handle方法
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); // Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. 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; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //就是上面這處
看看handle方法,因為被執行調用到,它返回ModelAndView
裏面return走的handleRequest是Controller接口的,找它的實現類
AbstractController抽象類,它有實現handleRequest
@Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { // Delegate to WebContentGenerator for checking and preparing. checkRequest(request); prepareResponse(response); // Execute handleRequestInternal in synchronized block if required. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { return handleRequestInternal(request, response); } } } return handleRequestInternal(request, response); }
看到最後面的那個返回值了嗎?是ModelAndView對象,它調用了handleRequestInternal(request,respone)這個方法
還記得AbstractController的實現類嗎?不是有種處理器的定義方法就是繼承AbstractController
package cn.dawn.day04abstractController; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Created by Dawn on 2018/3/19. */ //處理器 public class FirstController extends AbstractController { protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView me=new ModelAndView(); me.setViewName("index"); return me; } }
它的實現類默認要求必須實現handleRequestInternal(request,response)這個方法
所以,理清了吧,再一步步return回去,最後回到了中央調度器
結論,中央處理器DispatcherServlet通過處理器執行鏈找到handlerAdapter處理器適配器,後者調度了它的處理器,通過處理器處理,返回一個ModelAndView模型和視圖對象,一路返回,到中央調度器
SSM-SpringMVC-17:SpringMVC中深度剖析HandlerAdapter處理器適配器底層