摘要:而的類型在未來是極有可能變動或繼續追加的。設計者將與關聯,當追加新的類型以后,現有代碼并不需要改動,符合面向對象的又一原則開閉原則。處理器適配器與處理器映射器的作用類似,都是為了解耦合。優秀的程序員是藝術家,而藝術就是代碼。
先上一段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); // 根據當前請求獲取對應的處理器映射器 mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // 根據handler類型獲取對應的處理器適配器 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); } } } }
關注代碼中打中文注釋的兩個地方,一個獲取對應handler的處理器映射器,一個獲取對應handler的處理器適配器。那為什么需要這兩個東西,我們直接在handler中寫映射邏輯,直接通過handler來執行處理器方法難道不行嗎?答案是否定的,但Spring為什么要這樣做?有以下幾個好處
1.將具體的handler與handlerMapping分離開,為了符合單一職責
2.讓具體的處理器與DispatcherServlet解耦合,為了符合開閉原則
我們知道所有的處理器映射器都有共同的基類HandlerMapping,這個是可以確定的,也是不會改變的。而handler的類型在未來是極有可能變動或繼續追加的。當前版本Spring有以下幾種handler類型:
-HandlerMethod(通過RequestMappingHandlerMapping解析而來,我們最常使用的)
-Servlet(繼承自Servlet接口的處理器)
-Controller(繼承自Controller接口的處理器)
它們之前并沒有共同的基類,也不可能有共同的基類,因為它們來自不同的包,來自不同的設計者。
Spring設計者將DispatcherServlet與HandlerMapping關聯,當追加新的handler類型以后,現有代碼并不需要改動,符合面向對象的又一原則:開閉原則。
處理器適配器與處理器映射器的作用類似,都是為了解耦合。
if(handler instanceof Servlet){ (Servlet)handler.service(); }else if(handler instanceof HandlerMethod){ (ServletInvocableHandlerMethod)handler.invokeAndHandle(); }else if (handler instanceof Controller){ ((Controller) handler).handleRequest(); }
如果我們要新增一種處理器類型,必然要繼續追寫else if來進行處理,但使用處理器適配器后,DispatcherServlet不需要改動任何代碼,因為它只依賴HandlerAdapter,這樣DispatcherServlet與具體的Handler就解耦合了,它們之前可以獨立發展。
優秀的程序員是藝術家,而藝術就是代碼。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/74843.html
摘要:概述是目前主流的框架之一。這部分的詳細分析見深入淺出流程解析調用的具體方法處理請求,并返回一個。這部分的詳細分析見深入淺出流程解析視圖解析,遍歷的列表,獲取對應的對象,入口方法渲染,調用中獲取的的方法,完成對數據的渲染。 前言 其實一年前就想系統地記錄下自己閱讀spring源碼的收獲,搞一個深入淺出spring的系列文章,但是因為工作原因,遲遲沒有下筆。今天終于可以開始自己一年前的計劃...
摘要:問題來了,我們到底還在用嗎答案是,不全用。后者是初始化的配置,主要是的配置。啟動類測試啟動項目后,在瀏覽器里面輸入。通過查詢已裝載的,并且支持該而獲取的。按照前面對的描述,對于而言,這個必定是。的核心在的方法中。 之前已經分析過了Spring的IOC(《零基礎帶你看Spring源碼——IOC控制反轉》)與AOP(《從源碼入手,一文帶你讀懂Spring AOP面向切面編程》)的源碼,本次...
摘要:源碼倉庫本文倉庫三層結構表現層模型業務層持久層工作流程用戶前端控制器用戶發送請求前端控制器后端控制器根據用戶請求查詢具體控制器后端控制器前端控制器處理后結果前端控制器視圖視圖渲染視圖前端控制器返回視圖前端控制器用戶響應結 SpringMvc 【源碼倉庫】【本文倉庫】 三層結構 表現層 MVC模型 業務層 service 持久層 dao 工作流程 用戶->前端控制器:用戶...
摘要:是一個基于的框架??刂破鲗⒁晥D響應給用戶通過視圖展示給用戶要的數據或處理結果。有了減少了其它組件之間的耦合度。 相關閱讀: 本文檔和項目代碼地址:https://github.com/zhisheng17/springmvc 轉載請注明出處和保留以上文字! 了解 Spring: Spring 官網:http://spring.io/ 一個好的東西一般都會有一個好的文檔解釋說明,如果你...
閱讀 590·2021-11-22 14:45
閱讀 3083·2021-10-15 09:41
閱讀 1579·2021-10-11 10:58
閱讀 2806·2021-09-04 16:45
閱讀 2617·2021-09-03 10:45
閱讀 3247·2019-08-30 15:53
閱讀 1231·2019-08-29 12:28
閱讀 2143·2019-08-29 12:14