Spring學習筆記(四)--MVC概述

1、 飛機web

最近馬來西亞航空370號班機事故鬧得沸沸揚揚,情節整的撲朔迷離,連我在鑽研springMVC平和的心情都間接的受到了影響。正當我在想這個MVC的處理過程能夠怎樣獲得更好的理解呢?灰機,灰機… 同事的議論和天上的嗡嗡聲剎那間給了我一個答案,能夠和民航系統進行類比。spring

民航系統相似於一個專業處理旅行的系統,此係統中有一些對旅行去作的事好比出差等自己意義不大,只在旅行系統中才存在的術語。好比說安全

1. 航班MH370是一個航班代號,表示從吉隆坡到北京的航班;session

2. 航班時刻表來進行記錄,查找全部的飛行航班;mvc

3. 機票:在民航系統中惟一標識旅行者的token,上飛機須要飛機票,下飛機憑飛機票取行李;app

4. 安檢:檢查一下有沒有帶違禁品;工具

5. 飛機:完成從出發地到目的地的旅行;post

6. 機場:從乘客來看,無非是機票發售,安全檢查,提供航班的地方。url

 

回到web系統,一個url就是惟一標識一個處理邏輯的名稱。好比login.do就等於登錄邏輯的標識。HandlerMapping至關於航班時刻表,標識航班和對應的路線。HandlerMethod至關於處理航班的飛機,來完成從登機處到目的地的轉換。handlerAdapter 至關於從平常狀態處和飛行狀態轉換的適配工具,相似於機場。HandlerInterceptor至關於在這個轉換過程當中的共性處理邏輯,如購買機票,上飛機前要去憑身份證購買機票,到了目的地還要憑機票取行李等航班旅行通用的事項。spa

 

這四大組件構成了spring mvc 這個處理的基石。如圖所示:

 

sidajingang

圖1:四大組件

 

顯然,當進行旅行,須要完成從普通狀態到旅行狀態的適配,如將身份證和錢轉換成機票(在旅行中惟一標識本身身份的token) ,而後還要將行李存到飛機上;到了目的地機場後,就要進行旅行狀態到普通狀態的適配,使用機票進行取行李的操做。全部的登機過程都要經歷一些通用邏輯的處理,如進行安檢,進行行李託運/取回。這部分就構成了HandlerInterceptor的存在理由。

 

這四大組件充分的將web環境和業務邏輯環境解耦,使得業務邏輯能夠更關注業務自己,並將橫向的旅行邏輯和縱向的通用邏輯如安檢進行切割。這四大組件自己都是可擴展的,HandlerMethod最通用,爲方法級別的抽象。HandlerInteceptor是縱向邏輯的擴展接口,HandlerAdapter是從web環境到業務環境的適配擴展接口,HandlerMapping是將URL請求到業務邏輯映射的擴展接口。

 

1、 組件結構

HandlerMapping

Mapping

HanderAdapter

 

adapting

3、 處理過程:

  邏輯主要集中在org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)

 

A.根據請求(如url,參數,head等)特徵來獲得相應的方法和其匹配的攔截器集合。Spring mvc 3.0可用註解來標識處理邏輯方法和URL映射關係,所以涉及到掃描源代碼標識爲@Controller的類,並從中尋找@RequestMapping來進行映射表的生成。

mappedHandler = getHandler(processedRequest, false);

 

1. org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(HttpServletRequest)

獲取請求路徑lookupPath去尋找相應的handlerMethod方法

 

  1.1 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(String, HttpServletRequest)

 

     1.1.1 先將全部的映射按照requestURI來分組並存儲在urlMap中。urlMap中根據請求路徑找到對應的匹配列表,以進行進一步匹配。匹配列表中除請求的requestURI相同外,其餘某些特徵如方法,POST,GET,請求的head是不一樣的。

 

     1.1.2 org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfo, HttpServletRequest)

 

      先從請求中找到匹配條件,如method,params,produce,consume等條件,知足產生match

      並對這些match的匹配程度進行排序,獲得最匹配的match

 

2.getHandlerExecutionChain(handler, request)

   將匹配的Interceptor也加入,並返回

 

B.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

適配處理方法如何適配,會從request中獲得相應的parameter,session,Model等等,來支持自定義Controller的參數。

1. org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(HttpServletRequest, HttpServletResponse, Object) 進行適配

 

1.1 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(HttpServletRequest, HttpServletResponse, HandlerMethod)

 

1.2 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(HttpServletRequest, HttpServletResponse, HandlerMethod)

 

  1.2.1數據綁定方法和controller對應

  適配主要包含兩部分,調用參數的適配和返回結果的適配

 

C.HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();

獲得全部的interceptors而且將interceptors.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)進行逐個調用。

 

D.進行調用

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

 

E.全部的interceptors進行postHandle調用

interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);

 

F.org.springframework.web.servlet.DispatcherServlet.render(ModelAndView, HttpServletRequest, HttpServletResponse)渲染頁面

檢查mv 是不是引用,好比是字符串,並進行相應view 的解析

 

1.org.springframework.web.servlet.DispatcherServlet.resolveViewName(String, Map<String, Object>, Locale, HttpServletRequest)調用viewResolver.resolveViewName(viewName,locale);

 

2. view.render(mv.getModelInternal(), request, response)

 

G.最後調用interceptor的org.springframework.web.servlet.HandlerInterceptor.afterCompletion(HttpServletRequest, HttpServletResponse, Object, Exception)

相關文章
相關標籤/搜索