亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringMVC中的handlerMappings對(duì)象用法

 更新時(shí)間:2021年09月26日 14:31:56   作者:喜歡火影的木易楊  
這篇文章主要介紹了SpringMVC中的handlerMappings對(duì)象用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

從SpringMVC源碼解析所用的例子,一個(gè)http://localhost:9090/web/hi?name=yang請(qǐng)求調(diào)用到下面的地方,發(fā)現(xiàn)一個(gè)特殊的對(duì)象handlerMappings,通過請(qǐng)求uri去找handler的時(shí)候需要通過這個(gè)handlerMapping來找,那么handlerMappings是怎么樣的呢?

從斷點(diǎn)調(diào)試中,我們可以看到這handlerMappings一共有5個(gè),分別是WebMvcConfigurationSupportXXX,RequestMappingHandlerMapping和BeanNameUrlHandlerMapping。

首先,我們先了解一下這個(gè)handlerMappings是什么?從官方描述看,handlerMappings是DispatcherServlet內(nèi)部的一種Bean類型,DispatcherServlet內(nèi)部有很多Bean類型,包括HandlerMapping,HandlerAdapter,HandlerExceptionResolver,ViewResolver,LocaleResolver ,ThemesResolver,Multipart Resolver和FlashMapManager 。

其中HandlerMapping是一個(gè)將請(qǐng)求與用于預(yù)處理和后處理的攔截器列表一起映射起來的處理程序,除了WebMvcConfigurationSupportXXX供用戶自定義的映射處理器之外,

主要有以下兩種內(nèi)置類型:

(1)RequestMappingHandlerMapping(它支持@RequestMapping修飾的方法)

(2)SimpleUrlHandlerMapping(它為處理程序維護(hù)URI路徑模式的顯式注冊(cè))

一.handlerMappings集合內(nèi)部的元素是什么,有什么作用?

通過官方文檔描述,handlerMappings集合內(nèi)部最主要有兩種映射處理器類型RequestMappingHandlerMapping和SimpleUrlHandlerMapping,它們分別用于處理不同類型的Controller。

我們知道可以通過注解@Controller或@RestController注解方式來聲明一個(gè)Controller,然后使用@RequestMapping來修飾類名或方法名,這種方式其實(shí)是由RequestMappingHandlerMapping映射處理器來對(duì)請(qǐng)求地址和方法名進(jìn)行映射的;那么SimpleUrlHandlerMapping又用于處理哪種方式的Controller呢,那就是采用實(shí)現(xiàn)Controller接口或?qū)崿F(xiàn)HttpRequestHandler接口的類,這種聲明Controller的方式是早期的做法現(xiàn)在在實(shí)際開發(fā)中用的比較少了但是也是SpringMVC所支持的。

對(duì)于RequestMappingHandlerMapping

這種類型的handlerMapping是我們通過@RequestMapping+請(qǐng)求地址來修飾方法時(shí),會(huì)由這么一個(gè)映射器來對(duì)這種配置方式進(jìn)行解析和映射處理,也就是說RequestMappingHandlerMapping類型的映射器是為注解聲明方式的映射專門設(shè)計(jì)的,<K,V>映射關(guān)系會(huì)存儲(chǔ)在這個(gè)handlerMapping的Map中。

對(duì)于SimpleUrlHandlerMapping

這個(gè)映射器則是為繼承Controller類或?qū)崿F(xiàn)HttpRequestHandler接口的類進(jìn)行解析和映射處理的。

用代碼舉例子來驗(yàn)證,我們分別新建兩個(gè)類分別實(shí)現(xiàn)Controller接口和實(shí)現(xiàn)HttpRequestHandler接口,在類中寫請(qǐng)求接收方法,那么通過這兩種聲明的Controller通過請(qǐng)求地址在查詢請(qǐng)求方法時(shí)就會(huì)由SimpleUrlHandlerMapping進(jìn)行存儲(chǔ)和映射,<K,V>映射關(guān)系會(huì)存儲(chǔ)在這個(gè)SimpleUrlHandlerMapping的Map中。

(1)實(shí)現(xiàn)Controller接口的方式:

(2)實(shí)現(xiàn)HttpRequestHandler接口的方式:

然后重新進(jìn)行debug,使用http://localhost:9090/beanweb或http://localhost:9090/beanweb2請(qǐng)求,就會(huì)看到在handlerMapping中查找handler時(shí)會(huì)跳過第一種注解類型的RequestMappingHandlerMapping,而真正進(jìn)行解析處理的就是第二種非注解方式SimpleUrlHandlerMapping:

因此我們現(xiàn)在就明白了這個(gè)handlerMappings映射處理器集合的數(shù)據(jù)是怎么樣的,集合內(nèi)存儲(chǔ)的映射處理器分別處理怎么樣的請(qǐng)求。那么這個(gè)集合數(shù)據(jù)是怎么初始化的呢?

二.handlerMappings集合是怎么初始化的?

通過IDEAJ的Find Usages工具,在本文圖一的this.handlerMappings進(jìn)行調(diào)用搜索,可以一層層找到如下調(diào)用鏈:

HttpServletBean.init-->initServletBean()-->FrameworkServlet.initServletBean-->
FrameworkServlet.initWebApplicationContext-->FrameworkServlet.onRefresh
-->DispatcherServlet.onRefresh-->DispatcherServlet.initStrategies-->DispatcherServlet.initHandlerMappings
-->DispatcherServlet.getDefaultStrategies-->strategies.add((T) strategy)

通過前面SpringMVC前兩個(gè)流程的學(xué)習(xí)可知,DispatcherServlet繼承了FrameworkServlet,同時(shí)就集成了HttpServlet,也就是說DispatcherServlet本質(zhì)上就是一個(gè)Servlet,那么在容器加載這個(gè)Servlet的時(shí)候如果設(shè)置了<load-on-startup>加載時(shí)馬上進(jìn)行初始化,則在加載時(shí)會(huì)自動(dòng)執(zhí)行其init方法,于是就有了上面調(diào)用鏈的第一個(gè)HttpServletBean.init入口。

我們的目的是找到哪里進(jìn)行了handlerMappings的核心操作,通過調(diào)用關(guān)系我們找到核心代碼在DispatcherServlet.initHandlerMappings:

通過上面代碼返回的對(duì)象我們可以大膽推測(cè)matchingBeans就是我們要了解的handlerMappings集合,這個(gè)方法內(nèi)部完成了對(duì)多種類型HandlerMapping的初始化。通過查看我們重點(diǎn)關(guān)注的兩種映射器對(duì)象值,可以分別看到<K,V>關(guān)系:

上面就可以看到前面我們提到的urlLookup的Map集合以及handlerMap集合。為了了解這些不同的請(qǐng)求地址是怎么分配給不同類型的映射器來處理的,我們繼續(xù)點(diǎn)開這個(gè)核心方法:

實(shí)際由下面這行代碼完成了:

lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit)

而真正值得思考的邏輯在于

String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);

上面方法的邏輯就會(huì)自動(dòng)生成一個(gè)有5種類型handlerMapping的handlerMappings,那么這5種映射器是怎么產(chǎn)生的呢?

通過核心代碼我們可以知道,這里通過傳入一個(gè)type="HandlerMapping"的類型,在beanDefinitionNames的集合中匹配所有屬于HandlerMapping類型的BeanName,然后放入到result數(shù)組返回,然后在單例池中根據(jù)BeanName獲取對(duì)應(yīng)的HandlerMapping類型的Bean。

也就是說這些HandlerMapping映射處理器的生成是通過在BeanDefinition中匹配,如果匹配上了從單例池中獲取對(duì)應(yīng)類型的Bean,因此最后的handlerMappings中就有這5種類型了,至于請(qǐng)求路徑和方法名怎么作為K,V綁定到對(duì)應(yīng)映射器上的,由于個(gè)人閱讀源碼的能力有限這部分代碼小編還尚未理解,作為小編的一個(gè)未解之謎吧。

當(dāng)然,既然5種類型的映射器是通過BD來生成的,那這些BeanDefinition又是什么時(shí)候被加到Spring容器中的呢?

這就不得不提一下關(guān)于HandlerMapping映射處理器的配置文件:DispatchServlet.properties文件,這個(gè)文件就定義了哪些內(nèi)置使用的組件聲明。

實(shí)際上,通過上面源碼的調(diào)試,對(duì)于HandlerAdaper的流程和HandlerMapping其實(shí)是很類似的。

總結(jié)

(1)handlerMappings映射器集合內(nèi)部一共有5個(gè)不同類型的映射器

分別是WebMvcConfigurationSupportXXX,RequestMappingHandlerMapping和BeanNameUrlHandlerMapping,RequestMappingHandlerMapping映射處理器用于使用注解方式請(qǐng)求地址和方法名進(jìn)行映射的Controller,SimpleUrlHandlerMapping用于實(shí)現(xiàn)Controller接口或?qū)崿F(xiàn)HttpRequestHandler接口的Controller;

(2)handlerMappings映射器集合初始化會(huì)經(jīng)歷一個(gè)調(diào)用鏈

在DispatchServlet啟動(dòng)時(shí)自動(dòng)開始初始化,

HttpServletBean.init-->initServletBean()-->FrameworkServlet.initServletBean--> FrameworkServlet.initWebApplicationContext-->FrameworkServlet.onRefresh -->DispatcherServlet.onRefresh-->DispatcherServlet.initStrategies-->DispatcherServlet.initHandlerMappings -->DispatcherServlet.getDefaultStrategies-->strategies.add((T) strategy)

初始化的結(jié)果是產(chǎn)生一個(gè)handlerMappings映射器集合,內(nèi)部包含5種不同類型的映射器,每種映射器內(nèi)部由Map<K,V>來維護(hù)一個(gè)<請(qǐng)求地址,全限定方法名>的映射關(guān)系;

(3)handlerMappings映射器集合的每個(gè)映射處理器

是在初始化時(shí)就生成了BeanDefinition,通過BeanDefinitionName和傳入的type=HandlerMapping類型在所有BeanDefinitionNames集合中匹配所有的映射處理器,再從單例池中獲取其對(duì)應(yīng)Bean實(shí)例放入handlerMappings中;

(4)對(duì)于HandlerAdaper的初始化和HandlerMapping流程是類似的

(5)<請(qǐng)求地址全限定方法名>的映射關(guān)系

在哪里生成并維護(hù)到映射處理器中的,這部分代碼小編暫時(shí)還沒能了解到。

三.handlerMappings有什么擴(kuò)展?

我們知道,SpringMVC中不能直接通過url來訪問WEB-INF下的靜態(tài)資源,如我們?cè)诠こ蘷ebapp/jsp/新建一個(gè)1.jsp文件,通過

localhost:9090/jsp/1.jsp訪問時(shí)會(huì)報(bào)如下404錯(cuò)誤

但是SpringBoot卻可以通過url直接訪問webapp,static,resource等包下面的靜態(tài)資源,為什么會(huì)這樣呢?原因就在于SpringBoot對(duì)SpringMVC的handlerMappings進(jìn)行了自己的拓展。

之所以SpringMVC不能訪問靜態(tài)資源是因?yàn)閷?duì)于這種訪問靜態(tài)資源的請(qǐng)求,在handlerMappings內(nèi)沒有任何一個(gè)默認(rèn)的映射器可以進(jìn)行解析處理,因此自然這種請(qǐng)求就會(huì)被忽視。

對(duì)于SpringBoot來說,它自己實(shí)現(xiàn)了一個(gè)針對(duì)這種訪問靜態(tài)資源的映射處理器并交由handlerMappings來管理,因此就可以做到類似拓展,對(duì)于這個(gè)知識(shí)點(diǎn)在對(duì)SpringBoot學(xué)習(xí)時(shí)看能否研究一下這個(gè)特殊的映射處理器是怎么樣的,這里暫時(shí)知道這么一個(gè)結(jié)論即可。

到此關(guān)于handlerMappings對(duì)象的研究學(xué)習(xí)暫時(shí)到此,回到SpringMVC的主線流程邏輯中繼續(xù)學(xué)習(xí)后續(xù)的步驟。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mybatis的類型轉(zhuǎn)換接口TypeHandler

    Mybatis的類型轉(zhuǎn)換接口TypeHandler

    這篇文章主要介紹了Mybatis的類型轉(zhuǎn)換接口TypeHandler,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • Java中StringBuilder字符串類型的操作方法及API整理

    Java中StringBuilder字符串類型的操作方法及API整理

    Java中的StringBuffer類繼承于AbstractStringBuilder,用來創(chuàng)建非線程安全的字符串類型對(duì)象,下面即是對(duì)Java中StringBuilder字符串類型的操作方法及API整理
    2016-05-05
  • SpringBoot+@EnableScheduling使用定時(shí)器的常見案例

    SpringBoot+@EnableScheduling使用定時(shí)器的常見案例

    項(xiàng)目開發(fā)中經(jīng)常需要執(zhí)行一些定時(shí)任務(wù),本文主要介紹了SpringBoot+@EnableScheduling使用定時(shí)器的常見案例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • IDEA中scala生成變量后自動(dòng)顯示變量類型問題

    IDEA中scala生成變量后自動(dòng)顯示變量類型問題

    這篇文章主要介紹了IDEA中scala生成變量后自動(dòng)顯示變量類型問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • springBoot @Enable* 注解的使用

    springBoot @Enable* 注解的使用

    這篇文章主要介紹了springBoot @Enable* 注解的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-06-06
  • RxJava2 Scheduler使用實(shí)例深入解析

    RxJava2 Scheduler使用實(shí)例深入解析

    這篇文章主要為大家介紹了RxJava2 Scheduler使用實(shí)例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Java使用HttpClient詳細(xì)示例

    Java使用HttpClient詳細(xì)示例

    這篇文章介紹了Java使用HttpClient的詳細(xì)示例,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • Spring Boot 捕捉全局異常 統(tǒng)一返回值的問題

    Spring Boot 捕捉全局異常 統(tǒng)一返回值的問題

    這篇文章主要介紹了Spring Boot 捕捉全局異常 統(tǒng)一返回值,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 關(guān)于Spring AOP使用時(shí)的一些問題匯總

    關(guān)于Spring AOP使用時(shí)的一些問題匯總

    這篇文章主要給大家匯總介紹了關(guān)于Spring AOP使用時(shí)的一些問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • 簡述mybatis大于小于的轉(zhuǎn)義

    簡述mybatis大于小于的轉(zhuǎn)義

    這篇文章主要介紹了mybatis大于小于的轉(zhuǎn)義以及xml中常用轉(zhuǎn)義字符,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09

最新評(píng)論