最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringMVC中的handlerMappings對象用法

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

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

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

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

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

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

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

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

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

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

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

對于RequestMappingHandlerMapping

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

對于SimpleUrlHandlerMapping

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

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

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

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

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

因此我們現(xiàn)在就明白了這個handlerMappings映射處理器集合的數(shù)據(jù)是怎么樣的,集合內(nèi)存儲的映射處理器分別處理怎么樣的請求。那么這個集合數(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前兩個流程的學(xué)習(xí)可知,DispatcherServlet繼承了FrameworkServlet,同時就集成了HttpServlet,也就是說DispatcherServlet本質(zhì)上就是一個Servlet,那么在容器加載這個Servlet的時候如果設(shè)置了<load-on-startup>加載時馬上進(jìn)行初始化,則在加載時會自動執(zhí)行其init方法,于是就有了上面調(diào)用鏈的第一個HttpServletBean.init入口。

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

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

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

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

lbf.getBeansOfType(type, includeNonSingletons, allowEagerInit)

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

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

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

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

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

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

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

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

總結(jié)

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

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

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

在DispatchServlet啟動時自動開始初始化,

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

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

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

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

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

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

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

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

我們知道,SpringMVC中不能直接通過url來訪問WEB-INF下的靜態(tài)資源,如我們在工程webapp/jsp/新建一個1.jsp文件,通過

localhost:9090/jsp/1.jsp訪問時會報如下404錯誤

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

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

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

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

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

相關(guān)文章

  • Java中全局變量和局部變量詳解(看這篇就夠了)

    Java中全局變量和局部變量詳解(看這篇就夠了)

    在Java中全局變量和局部變量是兩種不同作用域的變量,這篇文章主要給大家介紹了關(guān)于Java中全局變量和局部變量的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),大家看這篇就夠了,需要的朋友可以參考下
    2023-11-11
  • Java微信分享接口開發(fā)詳解

    Java微信分享接口開發(fā)詳解

    這篇文章主要為大家詳細(xì)介紹了Java微信分享接口開發(fā)的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Java并發(fā)編程系列之LockSupport的用法

    Java并發(fā)編程系列之LockSupport的用法

    這篇文章主要為大家介紹了Java LockSupport的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助,希望能夠給你帶來幫助
    2021-11-11
  • java servlet結(jié)合mysql搭建java web開發(fā)環(huán)境

    java servlet結(jié)合mysql搭建java web開發(fā)環(huán)境

    之前寫過一篇 servlet+oracle的文章,但是那是因為公司有可能接那么一個項目,然后我當(dāng)時也比較閑,所以隨便學(xué)了下,那玩意是白去研究了,因為公司后面并沒接到那項目。
    2015-12-12
  • Java弱引用集合WeakHashMap總結(jié)

    Java弱引用集合WeakHashMap總結(jié)

    這篇文章主要介紹了Java弱引用集合WeakHashMap總結(jié),WeakHashMap利用WeakReference的弱引用特性讓用戶在使用的過程中不會因為沒有釋放Map中的資源而導(dǎo)致內(nèi)存泄露,WeakHashMap實(shí)現(xiàn)了Map接口,使用方式和其他的Map相同,需要的朋友可以參考下
    2023-09-09
  • 如何使用Idea搭建全注解式開發(fā)的SpringMVC項目

    如何使用Idea搭建全注解式開發(fā)的SpringMVC項目

    這篇文章主要介紹了如何使用Idea搭建全注解式開發(fā)的SpringMVC項目,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • springboot支持https請求的實(shí)現(xiàn)

    springboot支持https請求的實(shí)現(xiàn)

    本文主要介紹了springboot支持https請求的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Java中基于推、拉模式的sentinel規(guī)則持久化詳解

    Java中基于推、拉模式的sentinel規(guī)則持久化詳解

    這篇文章主要介紹了Java中基于推、拉模式的sentinel規(guī)則持久化詳解,推模式是sentinelDashboard?把規(guī)則推給Nacos,Nacos監(jiān)聽規(guī)則的變化推給微服務(wù),拉模式是sentinelDashboard?把規(guī)則直接給微服務(wù),?Nacos定時的同步微服務(wù)端的規(guī)則,需要的朋友可以參考下
    2023-09-09
  • idea項目文件夾橫向顯示,縱向顯示的解決方法

    idea項目文件夾橫向顯示,縱向顯示的解決方法

    這篇文章主要介紹了idea項目文件夾橫向顯示,縱向顯示的解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot+Quartz+數(shù)據(jù)庫存儲的完美集合

    SpringBoot+Quartz+數(shù)據(jù)庫存儲的完美集合

    這篇文章主要介紹了SpringBoot+Quartz+數(shù)據(jù)庫存儲的示例代碼,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02

最新評論

樟树市| 汕头市| 闵行区| 额尔古纳市| 故城县| 凌云县| 南和县| 罗田县| 赫章县| 石嘴山市| 惠来县| 玛纳斯县| 新宁县| 九龙县| 四川省| 西和县| 昭觉县| 万源市| 浦县| 盐边县| 桑植县| 石门县| 射阳县| 安达市| 库车县| 仁布县| 腾冲县| 云阳县| 英山县| 正定县| 江孜县| 南丹县| 资溪县| 樟树市| 革吉县| 武平县| 东乡| 郸城县| 晋州市| 大悟县| 灵武市|