国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

spring5源碼篇(12)——spring-mvc請求流程

這篇具有很好參考價值的文章主要介紹了spring5源碼篇(12)——spring-mvc請求流程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

spring-framework 版本:v5.3.19

一、請求流程

總體流程在 DispatchServelt#doDispatch 方法
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

1、處理器映射器

首先會獲取根據(jù)url去映射對應(yīng)的處理器(即接口執(zhí)行方法)
看到對應(yīng)的 getHandler 方法
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
為方便閱讀,進(jìn)入debug。可以看到springmvc默認(rèn)為我們注冊了三個handlerMapping。

springMvc中的各個組件如處理器映射器,處理器適配器,視圖解析器等是如何注入到容器的,先暫時不看,第二部分在看(問題1)。

1.1、 RequestMappingHandlerMapping

而其中我們最常用的一個就是RequestMappingHandlerMapping,所以這里只看這個類的 getHandler 方法(其實(shí)也是其抽象父類的方法)。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

1.2、獲取對應(yīng)的映射方法

getHandlerInternal 方法入手,看看是如何把一個請求映射到對應(yīng)的方法的。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
這里首先會從 mappingRegister 中去找可以根據(jù)url直接得到的映射(即沒有替換符),如果找不到再去所有注冊的映射中找,然后返回一個最匹配的映射對應(yīng)的處理器。

mappingRegister 可以簡單的理解成 Map<url,handler>。實(shí)際上,為提供效率一共維護(hù)了3個map
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
這些map是如何初始化的,第二部分再講(問題2)。

至于是如何匹配這些映射的,從 addMatchingMappings 入手
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
這里其實(shí)就是把匹配邏輯抽象成一個個condition,如果滿足所有 condition 說明這是一個可用的處理器。注意,僅是可用而已,并不一定會用這個處理器。因?yàn)榭赡芡瑫r會匹配到多個可用的處理器,但是最終只會返回最匹配的那一個。

1.3、添加攔截器

在前面的總體流程中注釋到,獲取處理器的時候,返回的是一個處理器鏈。因?yàn)榭赡軙渲糜袛r截器,而攔截器的添加從 getHandlerExecutionChain 入手。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
可以看到,就只是遍歷當(dāng)前 handlerMapping 所添加的所有攔截器,若匹配,則將該攔截器添加到處理器鏈中而已。至于 handlerMapping 的攔截器是如何添加的,第二部分再講(問題3)。

2、獲取合適的處理器適配器

spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
Spring MVC可能會有多種類型的處理器,例如控制器(Controller)、RESTful控制器等。處理器適配器負(fù)責(zé)選擇并調(diào)用合適的處理器來處理請求。這一步就是去獲取一個合適的處理器適配器,其實(shí)就是一個簡單遍歷獲取,在spring mvc 默認(rèn)提供的幾種適配器中,最常用的還是 RequestMappingHandlerAdapter

3、通過處理器適配器執(zhí)行處理器方法

3.1、攔截器的前置后置

在正式看處理器之前,順便提一嘴攔截器的執(zhí)行。
在執(zhí)行實(shí)際業(yè)務(wù)方法之前會先執(zhí)行處理器鏈中攔截器前置方法。同理,執(zhí)行完業(yè)務(wù)方法后會執(zhí)行處理器鏈中攔截器的后置方法。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
攔截器的執(zhí)行就是一個遍歷,就不上代碼了。

3.2、處理器的執(zhí)行

ha.handle 入手
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
不管是哪種適配器,最終都會依次通過 參數(shù)解析器、處理器、結(jié)果處理器 將方法返回值封裝成 ModelAndView 對象。

3.2.1 參數(shù)解析器解析參數(shù)和執(zhí)行處理器方法

從 invokeForRequest 入手
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
處理器方法的執(zhí)行就是反射實(shí)現(xiàn)的,沒啥好看的。主要看參數(shù)解析器是如何解析參數(shù)的。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
InvocableHandlerMethod 中維護(hù)了名為 resolvers 的 HandlerMethodArgumentResolverComposite 對象(多個參數(shù)解析器的封裝),并且這個變量的值是處理器適配器傳過來的。至于處理器適配器的參數(shù)解析器是哪來的,先暫時不看,后面第二部分再看(問題4)。這里只需知道參數(shù)解析器是在這里解析的以及值是處理器適配器傳過來的就可以了。

3.2.2 結(jié)果處理器處理結(jié)果

從 returnValueHandlers.handleReturnValue 入手
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
**跟參數(shù)解析器維護(hù)的復(fù)合對象一樣,也維護(hù)了一個名為 returnValueHandlers 的 HandlerMethodReturnValueHandlerComposite 復(fù)合對象,并且這個變量的值也是處理器適配器傳過來的。**至于處理器適配器的結(jié)果處理器是哪來的,也先暫時不看。

一般來說參數(shù)解析器的命名為 xxxMethodArgumentResolver 而結(jié)果處理器的命名為 xxxMethodReturnValueHandler。但是如果即是參數(shù)解析器又是結(jié)果處理器的命名就會xxxMethodProcessor。而我們常用的 RequestResponseBodyMethodProcessor 就是這種類型。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

3.2.3 消息轉(zhuǎn)化器

首先并不是所有的參數(shù)解析器或者結(jié)果處理器都會用到消息轉(zhuǎn)化器。,但至少我們最常用的 **RequestResponseBodyMethodProcessor 無論是解析參數(shù)還是處理結(jié)果,都會用到消息轉(zhuǎn)化器。**對應(yīng)的方法分別是 readWithMessageConverters,writeWithMessageConverters。并且write是直接寫到 http 的response,這也意味著 @ResponseBody 不需要通過視圖解析器解析渲染視圖。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

在 RequestResponseBodyMethodProcessor 中無論是read還是write,都會去遍歷參數(shù)解析器/結(jié)果處理器中維護(hù)的消息轉(zhuǎn)化器列表。至于 參數(shù)解析器/結(jié)果處理器的消息轉(zhuǎn)化器列表是哪里來的,也先暫時不看,后面在看(問題5)。

4、視圖解析器

試想這么一個接口,沒有 @ResponseBody 并且返回值是一個字符串。

如果有 @ResponseBody 注解,ModelAndView為null,無需解析渲染視圖。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
在我們配置如下的視圖解析器時會訪問到servlet容器下的mv.html頁面。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
從字符串到返回的具體頁面,這正是視圖解析器所做的事情。

關(guān)于視圖解析器,從 processDispatchResult 入手
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
解析:如果 ModelAndView 有視圖名(在上面的例子中視圖名就是方法返回的字符串)就會調(diào)用視圖解析器去解析視圖名得到一個視圖 View 對象,反之就從 ModelAndView 中直接獲取 View 對象??傊还茉鯓?,這里一定要有 View 對象,沒有就報錯。
渲染:然后再調(diào)用上一步得到的 View 對象 render 方法并將 ModelAndView 里的 Model 數(shù)據(jù)傳入,從而將數(shù)據(jù)渲染帶視圖上(如:jsp)。最后將渲染后的結(jié)果返回至前端。


至此一個完整的請求流程就看完了。為更形象記憶 spring mvc 各組件之間的關(guān)系,這里附上一張網(wǎng)圖
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

二、請求流程中的一些問題

1、各種組件如處理器映射器,處理器適配器,視圖解析器等是如何注入到spring容器的?

答:@EnableWebMvc注解(相當(dāng)于xml配置: <mvc:annotation-driven/>)。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
@EnableWebMvc 引入了 DelegatingWebMvcConfiguration,而這個類中就默認(rèn)注入了 spring mvc 的各種組件。
比如:
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

2、RequestMappingInfoHandlerMapping 處理器映射器中維護(hù)的映射map (即MapingRegister) 是如何初始化的?

答:在 RequestMappingInfoHandlerMapping bean生命周期的 afterPropertiesSet。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

3、處理器映射器中的攔截器是如何添加的?

答:以 RequestMappingInfoHandlerMapping 為例,在 DelegatingWebMvcConfiguration 注入處理器映射器的時就同時會去set攔截器。
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
其中 getInterceptors 代碼如下
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
說白了就是 getInterceptors 方法,會依次調(diào)用所有的 WebMvcConfigurer.addInteceptors 方法將自定義配置的攔截器添加到處理器映射器中的 InterceptorRegistry。之后處理器映射器在映射處理器時,將其中匹配的攔截器添加到處理鏈,進(jìn)而實(shí)現(xiàn)攔截器的效果。

正是因?yàn)樽詣幼⑷氲脑?,所以我們平時配置spring mvc時只需注入一個實(shí)現(xiàn) WebMvcConfigurer 接口的類。

但其實(shí)截至目前為止添加的還只是一個原始版本的攔截器,真正使用的攔截器是適配后的版本。
適配的時機(jī)是在處理器映射器生命周期的 setApplicationContext 方法。(最后會調(diào)用到 initApplicationContext)
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

4、處理器適配器的參數(shù)解析器和結(jié)果處理器是如何來的?

答:在 RequestMappingHandlerAdapter bean生命周期的 afterPropertiesSet。

spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
具體添加了哪些參數(shù)解析器,結(jié)果處理器就不細(xì)看了,太多了…

5、參數(shù)解析器/結(jié)果處理器中的消息轉(zhuǎn)化器是如何來的?

答:來自處理器適配器,而處理器適配器的消息轉(zhuǎn)化器來自 WebMvcConfigurer 配置或者默認(rèn)配置。

如下圖:
(參數(shù)解析器/結(jié)果處理器中的消息轉(zhuǎn)化器來自處理器適配器)
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java
(適配器的來自 WebMvcConfigurer 配置或者默認(rèn)配置)
spring5源碼篇(12)——spring-mvc請求流程,Spring,spring,mvc,java

至于this.configurers.configureMessageConverters(converters);
首先configurers在前面第三個問題已經(jīng)看過了,就是自動注入的 WebMvcConfigurer 總和。所以這句總的來說就是依次調(diào)用所有的 WebMvcConfigurer.configureMessageConverters 方法將自定義配置的消息添加到處理器適配器中。文章來源地址http://www.zghlxwxcb.cn/news/detail-618983.html

到了這里,關(guān)于spring5源碼篇(12)——spring-mvc請求流程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring、Spring-MVC、Mybatis、Mybatis-generator整合核心配置文件記錄

    Spring、Spring-MVC、Mybatis、Mybatis-generator整合核心配置xml文件記錄 spring-mybatis.xml

    2024年01月22日
    瀏覽(50)
  • Spring-MVC使用JSR303及攔截器,增強(qiáng)網(wǎng)絡(luò)隱私安全

    Spring-MVC使用JSR303及攔截器,增強(qiáng)網(wǎng)絡(luò)隱私安全

    目錄 一、JSR303 ( 1 )? 是什么 ( 2 )? 作用 ( 3 )??常用注解 ( 4 )? 入門使用 二、攔截器 2.1? 是什么 2.2? 攔截器與過濾器的區(qū)別 2.3? 應(yīng)用場景 2.4 基礎(chǔ)使用 2.5?用戶登錄權(quán)限控制 給我們帶來的收獲 JSR 303是Java規(guī)范請求(Java Specification Request)的一部分, 它定義了一套標(biāo)準(zhǔn)的Jav

    2024年02月09日
    瀏覽(31)
  • Spring MVC是什么?詳解它的組件、請求流程及注解

    Spring MVC是什么?詳解它的組件、請求流程及注解

    作者: Insist-- 個人主頁: insist--個人主頁 作者會持續(xù)更新網(wǎng)絡(luò)知識和python基礎(chǔ)知識,期待你的關(guān)注 前言 本文將講解Spring MVC是什么,它的優(yōu)缺點(diǎn)與九大組件,以及它的請求流程與常用的注解。 目錄 一、Spring MVC是什么? 二、Spring MVC的優(yōu)缺點(diǎn) 1、優(yōu)點(diǎn) 2、缺點(diǎn) 三、Spring MVC的九

    2024年02月12日
    瀏覽(19)
  • spring-mvc系列:詳解@RequestMapping注解(value、method、params、header等)

    spring-mvc系列:詳解@RequestMapping注解(value、method、params、header等)

    目錄 一、@RequestMapping注解的功能 二、@RequestMapping注解的位置 三、@RequestMapping注解的value屬性 四、@RequestMapping注解的method屬性 五、@RequestMapping注解的params屬性 六、@RequestMapping注解的header屬性 七、SpringMVC支持ant分格的路徑 八、SpringMVC支持路徑中的占位符 從注解名稱上我們可

    2024年02月14日
    瀏覽(20)
  • Spring-mvc的參數(shù)傳遞與常用注解的解答及頁面的跳轉(zhuǎn)方式---綜合案例

    Spring-mvc的參數(shù)傳遞與常用注解的解答及頁面的跳轉(zhuǎn)方式---綜合案例

    目錄 一.slf4j--日志 二.常用注解 ??? ? ?2.1.@RequestMapping ??????2.2.@RequestParam ??????2.3.@RequestBody ??????2.4.@PathVariable 三.參數(shù)的傳遞 3.1 基礎(chǔ)類型 3.2 復(fù)雜類型 3.3?@RequestParam 3.4? @PathVariable 3.5 @RequestBody 3.6 增刪改查? 四.返回值? ????????? 4.1 void 返回值? ?4.2 String

    2024年02月09日
    瀏覽(28)
  • spring5源碼篇(9)——mybatis-spring整合原理

    spring5源碼篇(9)——mybatis-spring整合原理

    spring-framework 版本:v5.3.19 spring和mybatis的整合無非主要就是以下幾個方面: 1、SqlSessionFactory怎么注入? 2、Mapper代理怎么注入? 3、為什么要接管mybatis事務(wù)? 在mybatis-spring中,定義了一個新的factoryBean——SqlSessionFactoryBean,我們將其注入到spring容器即可。 其實(shí)也不難猜到,這

    2024年02月03日
    瀏覽(25)
  • 【Spring】Spring MVC請求響應(yīng)

    【Spring】Spring MVC請求響應(yīng)

    訪問不同的路徑, 就是發(fā)送不同的請求。在發(fā)送請求時, 可能會帶?些參數(shù), 所以學(xué)習(xí)Spring的請求, 主要是學(xué)習(xí)如何傳遞參數(shù)到后端以及后端如何接收。 傳遞參數(shù),我們通過postman測試。 正常傳遞: 可以看到, 后端程序正確拿到了name參數(shù)的值。 Spring MVC 會根據(jù)?法的參數(shù)名, 找

    2024年02月08日
    瀏覽(27)
  • 12 擴(kuò)展Spring MVC

    12 擴(kuò)展Spring MVC

    ? ? ? ? ? 頁面跳轉(zhuǎn)功能:訪問localhost:8081/jiang會自動跳轉(zhuǎn)到另一個頁面。 ? ? ? ? 首先,在config包下創(chuàng)建一個名為MyMvcConfig的配置類: ? ? ? ? ?類上加入@Configuration注解,類實(shí)現(xiàn)WebMvcConfiger接口,實(shí)現(xiàn)里面的視圖跳轉(zhuǎn)方法addViewConrollers: ? ? ? ? 注意:在轉(zhuǎn)發(fā)的地址中,不

    2024年02月15日
    瀏覽(20)
  • Spring MVC:請求轉(zhuǎn)發(fā)與請求重定向

    Spring MVC:請求轉(zhuǎn)發(fā)與請求重定向

    轉(zhuǎn)發(fā)( forward ) ,指服務(wù)器接收請求后,從一個資源跳轉(zhuǎn)到另一個資源中。請求轉(zhuǎn)發(fā)是一次請求,不會改變?yōu)g覽器的請求地址。 簡單示例: 1.通過 String 類型的返回值實(shí)現(xiàn)轉(zhuǎn)發(fā)

    2024年02月08日
    瀏覽(23)
  • Spring MVC 請求參數(shù)綁定

    Spring MVC 請求參數(shù)綁定

    Spring MVC 是一個用于構(gòu)建 Web 應(yīng)用程序的框架,它提供了一種方便的方式來處理 HTTP 請求和響應(yīng)。在 Spring MVC 中,請求參數(shù)綁定是將 HTTP 請求中的參數(shù)映射到控制器方法的參數(shù)上的過程。Spring MVC 提供了多種方式來實(shí)現(xiàn)請求參數(shù)綁定。 請求參數(shù)綁定:說?了SpringMVC如何接收請求

    2024年02月07日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包