摘要:而的類型在未來是極有可能變動或繼續(xù)追加的。設(shè)計者將與關(guān)聯(lián),當(dāng)追加新的類型以后,現(xiàn)有代碼并不需要改動,符合面向?qū)ο蟮挠忠辉瓌t開閉原則。處理器適配器與處理器映射器的作用類似,都是為了解耦合。優(yōu)秀的程序員是藝術(shù)家,而藝術(shù)就是代碼。
先上一段Spring MVC核心類DispatcherServlet中最重要的方法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); // 根據(jù)當(dāng)前請求獲取對應(yīng)的處理器映射器 mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // 根據(jù)handler類型獲取對應(yīng)的處理器適配器 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()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we"re processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", 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); } } } }
關(guān)注代碼中打中文注釋的兩個地方,一個獲取對應(yīng)handler的處理器映射器,一個獲取對應(yīng)handler的處理器適配器。那為什么需要這兩個東西,我們直接在handler中寫映射邏輯,直接通過handler來執(zhí)行處理器方法難道不行嗎?答案是否定的,但Spring為什么要這樣做?有以下幾個好處
1.將具體的handler與handlerMapping分離開,為了符合單一職責(zé)
2.讓具體的處理器與DispatcherServlet解耦合,為了符合開閉原則
我們知道所有的處理器映射器都有共同的基類HandlerMapping,這個是可以確定的,也是不會改變的。而handler的類型在未來是極有可能變動或繼續(xù)追加的。當(dāng)前版本Spring有以下幾種handler類型:
-HandlerMethod(通過RequestMappingHandlerMapping解析而來,我們最常使用的)
-Servlet(繼承自Servlet接口的處理器)
-Controller(繼承自Controller接口的處理器)
它們之前并沒有共同的基類,也不可能有共同的基類,因為它們來自不同的包,來自不同的設(shè)計者。
Spring設(shè)計者將DispatcherServlet與HandlerMapping關(guān)聯(lián),當(dāng)追加新的handler類型以后,現(xiàn)有代碼并不需要改動,符合面向?qū)ο蟮挠忠辉瓌t:開閉原則。
處理器適配器與處理器映射器的作用類似,都是為了解耦合。
if(handler instanceof Servlet){ (Servlet)handler.service(); }else if(handler instanceof HandlerMethod){ (ServletInvocableHandlerMethod)handler.invokeAndHandle(); }else if (handler instanceof Controller){ ((Controller) handler).handleRequest(); }
如果我們要新增一種處理器類型,必然要繼續(xù)追寫else if來進行處理,但使用處理器適配器后,DispatcherServlet不需要改動任何代碼,因為它只依賴HandlerAdapter,這樣DispatcherServlet與具體的Handler就解耦合了,它們之前可以獨立發(fā)展。
優(yōu)秀的程序員是藝術(shù)家,而藝術(shù)就是代碼。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/74843.html
摘要:概述是目前主流的框架之一。這部分的詳細分析見深入淺出流程解析調(diào)用的具體方法處理請求,并返回一個。這部分的詳細分析見深入淺出流程解析視圖解析,遍歷的列表,獲取對應(yīng)的對象,入口方法渲染,調(diào)用中獲取的的方法,完成對數(shù)據(jù)的渲染。 前言 其實一年前就想系統(tǒng)地記錄下自己閱讀spring源碼的收獲,搞一個深入淺出spring的系列文章,但是因為工作原因,遲遲沒有下筆。今天終于可以開始自己一年前的計劃...
摘要:問題來了,我們到底還在用嗎答案是,不全用。后者是初始化的配置,主要是的配置。啟動類測試啟動項目后,在瀏覽器里面輸入。通過查詢已裝載的,并且支持該而獲取的。按照前面對的描述,對于而言,這個必定是。的核心在的方法中。 之前已經(jīng)分析過了Spring的IOC(《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》)與AOP(《從源碼入手,一文帶你讀懂Spring AOP面向切面編程》)的源碼,本次...
摘要:源碼倉庫本文倉庫三層結(jié)構(gòu)表現(xiàn)層模型業(yè)務(wù)層持久層工作流程用戶前端控制器用戶發(fā)送請求前端控制器后端控制器根據(jù)用戶請求查詢具體控制器后端控制器前端控制器處理后結(jié)果前端控制器視圖視圖渲染視圖前端控制器返回視圖前端控制器用戶響應(yīng)結(jié) SpringMvc 【源碼倉庫】【本文倉庫】 三層結(jié)構(gòu) 表現(xiàn)層 MVC模型 業(yè)務(wù)層 service 持久層 dao 工作流程 用戶->前端控制器:用戶...
摘要:是一個基于的框架。控制器將視圖響應(yīng)給用戶通過視圖展示給用戶要的數(shù)據(jù)或處理結(jié)果。有了減少了其它組件之間的耦合度。 相關(guān)閱讀: 本文檔和項目代碼地址:https://github.com/zhisheng17/springmvc 轉(zhuǎn)載請注明出處和保留以上文字! 了解 Spring: Spring 官網(wǎng):http://spring.io/ 一個好的東西一般都會有一個好的文檔解釋說明,如果你...
閱讀 582·2021-11-22 14:45
閱讀 3070·2021-10-15 09:41
閱讀 1555·2021-10-11 10:58
閱讀 2797·2021-09-04 16:45
閱讀 2606·2021-09-03 10:45
閱讀 3238·2019-08-30 15:53
閱讀 1221·2019-08-29 12:28
閱讀 2133·2019-08-29 12:14