SpringMVC源碼學習經歷(識圖解析器篇)

(Notice:以下所有經驗也是我根據(jù)網上的經驗整理的,如有侵權可以聯(lián)系我刪除,歡迎交流和溝通,Wx:IT_Ezra,QQ 654303408。 有問題討論也可聯(lián)系我。)

(PS:SpringMVC是目前主流的Web MVC框架之一,其工作流程我在之前的文章中介紹了,下面我想重點講一下SprignMVC的識圖解析器。)

image.png

(PS:我認為最最最核心的流程:下馬威)

首先,我們可以根據(jù)這個圖把整個流程走一遍。首先來了一個請求,然后通過DispatcherServlet,DispatcherServlet的init加載的mapperHandler類的getHandler()方法得到handler,DispatcherServlet的init加載的RequestMappingHandlerAdapter類的handle()方法返回ModelAndView, 然后把ModelAndView傳到視圖解析器(InternalResourceViewResolver)解析,InternalResourceViewResolver繼承了UrlBasedViewResolver類,UrlBasedViewResolver類繼承AbstractCachingViewResolver抽象類,AbstractCachingViewResolver抽象類會首先createView()方法,其內部調用loadView()方法,loadView()方法里面調用了buildView()方法,然后返回一個InternalResourceView視圖。

------------------------------------------------------------------------------------------------------

然后開始介紹重要的借口和類。
  • 1.View接口

視圖基礎接口,它的各種實現(xiàn)是么有狀態(tài)的,所以也是線程安全的。該接口定義了兩個方法。
View接口

  • 2. AbstractView抽象類

View接口的基礎實現(xiàn)類。我們稍微介紹一下這個抽象類。
AbstractView抽象類
其中非常重要的一個方法render方法,該方法里面有一個抽象方法renderMergedOutputModel方法(AbstractView抽象類定義的抽象方法,為View接口提供的render方法服務)。
render方法
  • 3. AbstractUrlBasedView抽象類

繼承自AbstractView抽象類,增加了1個類型為String的url參數(shù)。
  • 4. InternalResourceView類(重點類,我們在配置Springmvc的時候經常會看到它的配置)

繼承自AbstractUrlBasedView抽象類的類,表示JSP視圖。
我們看下這個類的renderMergedOutputModel方法(AbstractView抽象類定義的抽象方法,為View接口提供的render方法服務)。這個抽象類里面可一看到最后決定用include方法還是forward方法。這兩個方法都是重定向方法,但是區(qū)別不同的是,惟一的不同在于:利用include()方法將HTTP請求轉送給其他Servlet后,被調用的Servlet雖然可以處理這個HTTP請求,但是最后的主導權仍然是在原來的Servlet。RequestDispatcher是一個Web資源的包裝器,可以用來把當前request傳遞到該資源,或者把新的資源包括到當前響應中。
renderMergedOutputModel

我們在SpringMVC的配置文件里面,會配置視圖解析器,目前主流的就是InternalResourceView類,當然它的實現(xiàn)也是依賴于另一個抽象類AbstractCachingViewResolver(后文會講到)。我們繼續(xù)介紹其他類和接口

   <!-- 視圖解析器 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前綴 -->
        <property name="prefix">
            <value>/WEB-INF/</value>
        </property>
        <!-- 后綴 -->
        <property name="suffix">
            <value>.html</value>
        </property>
    </bean>
  • 5. JstlView類

JSTL視圖,繼承自InternalResourceView,該類大致上與InternalResourceView類一致。
  • 6. AbstractTemplateView抽象類

繼承自AbstractUrlBasedView抽象類,重寫了renderMergedOutputModel方法,在該方法中會調用renderMergedTemplateModel方法,renderMergedTemplateModel方法為新定義的抽象方法。
該抽象類有幾個boolean屬性exposeSessionAttributes,exposeRequestAttributes。 設置為true的話會將request和session中的鍵值和值丟入到renderMergedTemplateModel方法中的model這個Map參數(shù)中。
這個類是某些模板引擎視圖類的父類。 比如FreemarkerView,VelocityView。
  • 7. ViewResolver接口

視圖解釋器,用來解析視圖View,與View接口配合使用。
該接口只有1個方法,通過視圖名稱viewName和Locale對象得到View接口實現(xiàn)類:
  • 8. AbstractCachingViewResolver抽象類

帶有緩存功能的ViewResolver接口基礎實現(xiàn)抽象類,該類有個屬性名為viewAccessCache的以 "viewName_locale" 為key, View接口為value的Map。
該抽象類實現(xiàn)的resolveViewName方法內部會調用createView方法,方法內部會調用loadView抽象方法。
  • 9. UrlBasedViewResolver類

繼承自AbstractCachingViewResolver抽象類、并實現(xiàn)Ordered接口的類,是ViewResolver接口簡單的實現(xiàn)類
AbstractCachingViewResolver
該類復寫了createView方法:
createView
父類(AbstractCachingViewResolver)的createView方法內部會調用loadView抽象方法,UrlBasedViewResolver實現(xiàn)了這個抽象方法:
image
image
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
  <property name="prefix" value="/WEB-INF/view/"/>
  <property name="suffix" value=".jsp"/>
  <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
  <property name="viewNames">
    <array>  
      <value type="java.lang.String">*</value>  
    </array>    
  </property>  
  <property name="contentType" value="text/html;charset=utf-8"/>
  <property name="attributesMap">
    <map>
      <entry key="mytest" value="mytestvalue"/>
    </map>
  </property>
  <property name="attributes">
    <props>
      <prop key="test">testvalue</prop>
    </props>
  </property>
</bean>
我們看到:以InternalResourceView這個JSP視圖作為視圖;viewNames我們設置了,這里的代表全部視圖名(這個viewNames屬性不設置也可以,代表全部視圖名都處理);http響應頭部contentType信息:text/html;charset=utf-8;attributesMap和attributes傳入的Map和Properties參數(shù)都會被丟入到staticAttributes屬性中,這個staticAttributes會被設置成AbstractView的staticAttributes屬性,也就是request域中的參數(shù)。
image
image
image
我們看到request域中沒有設置mytest和testvalue值。但是頁面中會顯示,因為我們配置了attributesMap和attributes參數(shù)。
如果我們把viewNames中的"*"改成"index1"。那么就報錯了,因為處理視圖名的時候index匹配不上index1。
image
  • 10. InternalResourceViewResolver類

繼承自UrlBasedViewResolver,以InternalResourceView作為視圖,若項目中存在“javax.servlet.jsp.jstl.core.Config”該類,那么會以JstlView作為視圖。重寫了buildView方法,主要就是為了給InternalResourceView視圖設置屬性
  • 11. ModelAndView對象

顧名思義,帶有視圖和Model屬性的一個模型和視圖類。
image
值得注意的是,這個視圖屬性是一個Object類型的數(shù)據(jù),可以直接是View接口的實現(xiàn)類或者視圖名(字符串)。

-------------------------------------------------------------------------------------------------------------------------------------------

下面我們來分析SpringMVC處理視圖的源碼。

SpringMVC在處理請求的時候,通過RequestMappingHandlerMapping得到HandlerExecutionChain,然后通過RequestMappingHandlerAdapter得到1個ModelAndView對象,之后通過processDispatchResult方法處理。processDispatchResult方法如下:
image
image
如果配置的ViewResolver如下:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/view/"/>
  <property name="suffix" value=".jsp"/>
</bean>

那么就是使用InternalResourceViewResolver來解析視圖。之前分析過,InternalResourceViewResolver重寫了UrlBasedViewResolver的buildView方法。但是還是會調用UrlBasedViewResolver的buildView方法。

image
最終得到InternalResourceView或JstlView視圖。這兩個視圖的render方法本文介紹重要接口及類的時候已分析。

特別參考[Format大佬的分享]http://www.cnblogs.com/fangjian0423/p/springMVC-view-viewResolver.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容