SprngMVC源碼學習

來源:互聯網
上載者:User

標籤:this   async   技術   protected   pos   control   style   主題   mode   

 

運行helloWorld樣本進入調試介面。 

 

 DispatcherServlet:前端控制器

DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) line: 945    DispatcherServlet.doService(HttpServletRequest, HttpServletResponse) line: 876    DispatcherServlet(FrameworkServlet).processRequest(HttpServletRequest, HttpServletResponse) line: 931    DispatcherServlet(FrameworkServlet).doGet(HttpServletRequest, HttpServletResponse) line: 822    DispatcherServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 624    DispatcherServlet(FrameworkServlet).service(HttpServletRequest, HttpServletResponse) line: 807    DispatcherServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 731    

由上進入源碼查看

DispatcherServlet(FrameworkServlet).service(HttpServletRequest, HttpServletResponse) line: 807
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {  ...service();}

  

HttpServletBean 的實現
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {}

 

 

 接下來重點關注doDispatch()

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.                //1、根據當前請求地址找到哪個處理器來處理請求                mappedHandler = getHandler(processedRequest);                if (mappedHandler == null || mappedHandler.getHandler() == null) {                     //2、如果找不到報錯                    noHandlerFound(processedRequest, response);                    return;                }                // Determine handler adapter for the current request.                //2\為當前請求確定適配器                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()) {                        String requestUri = urlPathHelper.getRequestUri(request);                        logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);                    }                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {                        return;                    }                }                if (!mappedHandler.applyPreHandle(processedRequest, response)) {                    return;                }                try {                    // Actually invoke the handler.                    //真正執行方法                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());                }                finally {                    if (asyncManager.isConcurrentHandlingStarted()) {                        return;                    }                }                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                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);                return;            }            // Clean up any resources used by a multipart request.            if (multipartRequestParsed) {                cleanupMultipart(processedRequest);            }        }    }
四步:1)、所有請求進來都經過DispatcherServlet的900:doDispatch()方法(包含了處理請求以及響應的所有流程)2)、916;getHandler(processedRequest);根據當前請求擷取到能處理這個請求的Controller對象3)、923:找到能執行這個Controller對象裡面每一個方法的適配器4)、945:ha.handle適配器調用目標方法(利用反射調用方法)5)、959:轉寄到頁面(處理響應結果)processDispatchResult  
1、根據當前請求地址找到哪個處理器來處理請求                mappedHandler = getHandler(processedRequest);

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {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;}

  

 

SpringfMVC啟動的時候掃描所有的註解,將每一個類的每一個方法能處理什麼請求都已經儲存在handlerMapping中了;DefaultAnnotationHandlerMapping;
2、為當前請求確定適配器
 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
找到能調用這個類裡面每個方法的適配器;適配器利用反射調用方法; 
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");}

  

我們都使用註解模式的所以適配器使用第三個;

 

3、SpringMVC中DispatcherServlet的幾個重要屬性,以及賦值SpringMVC九大組件; 
/** MultipartResolver used by this servlet 檔案上傳解析器*/    private MultipartResolver multipartResolver;    /** LocaleResolver used by this servlet 國際化解析器*/    private LocaleResolver localeResolver;    /** ThemeResolver used by this servlet 主題解析器*/    private ThemeResolver themeResolver;    /** List of HandlerMappings used by this servlet 儲存了請求與類的映射關係(哪個請求用哪個類來處理)*/    private List<HandlerMapping> handlerMappings;    /** List of HandlerAdapters used by this servlet適配器;用來執行控制器(處理器)目標方法的*/    private List<HandlerAdapter> handlerAdapters;    /** List of HandlerExceptionResolvers used by this servlet 異常解析器*/    private List<HandlerExceptionResolver> handlerExceptionResolvers;    /** RequestToViewNameTranslator used by this servlet 轉化器*/    private RequestToViewNameTranslator viewNameTranslator;    /** FlashMapManager used by this servletFlashMap 管理器 */    private FlashMapManager flashMapManager;    /** List of ViewResolvers used by this servlet視圖解析器 */    private List<ViewResolver> viewResolvers;

 

檔案上傳組件預設沒值;預設賦值;     protected  void initStrategies(ApplicationContext context) {         //預設從ioc容器中擷取id為multipartResolver的組件,如果沒有擷取到就賦值為null;        initMultipartResolver(context);         //按照id擷取localeResolver;如果沒有;        initLocaleResolver(context);        initThemeResolver(context);        initHandlerMappings(context);        initHandlerAdapters(context);        initHandlerExceptionResolvers(context);        initRequestToViewNameTranslator(context);        initViewResolvers(context);        initFlashMapManager(context);    } //1、有些組件是這麼》?先擷取使用者配置的,如果沒有可以使用預設的(MultipartResolver )//2、有些組件是拿id擷取的;有些是拿類型擷取的,//3、給SpringMVC中配置九大之一的某個組件;如果是拿id‘擷取的?id不要亂寫,用指定id;//如果是用類型擷取,id可以不用寫;       在於DispatcherServlet.class同目錄下有一個properties檔案,這裡封裝了所有組件預設的類型;  

SprngMVC源碼學習

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.