帶著問題閱讀源碼——Spring MVC是如何將url注冊到RequestMappingHandlerMapping?

背景

在 Spring MVC 中,DispatcherServlet 是前端控制器(front controller),它負責接收所有的 HTTP 請求并將它們映射到相應的處理器(handler)。為了實現這一點,Spring MVC 使用了適配器模式將 Controller 與 DispatcherServlet 綁定在一起。

在Spring MVC的優雅設計中,所有公開的接口默認都通過RequestMappingHandlerMapping進行映射轉換。這一過程的核心在于如何將這些接口有效地注冊到RequestMappingHandlerMapping。本文將深入探討這一機制,揭開其背后的原理和細節,這是我們研究的主要焦點。

RequestMappingHandlerMapping介紹

RequestMappingHandlerMapping 是 Spring MVC 中的一個類,用于將請求映射到處理器方法。它是 AbstractHandlerMethodMapping 的一個具體實現,提供了一些默認的請求映射策略。

在 Spring MVC 中,HandlerMapping 負責將請求映射到相應的處理器方法。RequestMappingHandlerMapping 提供了一個基本的框架,可以自定義擴展以支持不同的請求映射方式。例如,可以通過繼承RequestMappingHandlerMapping 并重寫其中的方法來實現自定義的請求映射策略。

具體來說,RequestMappingHandlerMapping 主要包含以下幾個關鍵部分:

  • registerHandlerMethod 方法:該方法用于注冊一個處理器方法。它首先檢查該處理器方法是否已經注冊過,如果沒有則將其添加到內部維護的處理器方法列表中。

  • getHandlerInternal 方法:該方法根據請求信息獲取對應的處理器方法。它首先通過lookupHandlerMethod 方法查找匹配的處理器方法,然后通過 instantiateHandlerMethod 方法實例化處理器方法對象。

  • lookupHandlerMethod 方法:該方法根據請求信息查找匹配的處理器方法。它首先通過extractPathWithinApplication 方法提取請求路徑中的應用程序路徑,然后通過 matches 方法匹配處理器方法。如果找到匹配的處理器方法,則返回該處理器方法;否則返回 null。

  • matches 數組:該方法根據請求信息和處理器方法進行匹配。它首先檢查請求路徑是否與處理器方法的 URL 模式匹配,然后檢查請求方法是否與處理器方法的 HTTP 方法匹配。如果兩個條件都滿足,則認為匹配成功。

  • handleMatch 方法:該方法處理匹配成功的處理器方法。它首先調用 preHandle 方法進行預處理,然后調用處理器方法執行業務邏輯,最后調用 afterCompletion 方法進行后處理。

注冊過程

AbstractHandlerMethodMapping是Spring MVC中用于處理請求映射的抽象類。它提供了一些基本的方法,如獲取處理器方法、處理方法參數等。具體的實現類需要繼承這個抽象類并實現相應的方法。

AbstractHandlerMethodMapping 中的 detectHandlerMethods 方法是用于從處理器中獲取處理器方法并注冊的。這個方法是一個受保護的方法,它的作用是檢測帶有特定注解(如@RequestMapping)的方法,并將這些方法注冊到映射器中,以便后續可以根據請求找到對應的處理器方法來處理請求。

具體來說,detectHandlerMethods 方法會執行以下步驟:

  • 獲取handler的類型:如果傳入的handler是字符串類型,則將其轉換為對應的類類型。
	Class<?> handlerType = (handler instanceof String ?obtainApplicationContext().getType((String) handler) : handler.getClass());
  • 檢測handler的方法:遍歷handler的所有方法,檢測哪些方法帶有特定的注解(如@RequestMapping),這些方法被視為處理器方法。
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,(MethodIntrospector.MetadataLookup<T>) method -> {try {return getMappingForMethod(method, userType);}catch (Throwable ex) {throw new IllegalStateException("Invalid mapping on handler class [" +userType.getName() + "]: " + method, ex);}});
  • 注冊處理器方法:將檢測到的處理器方法注冊到映射器中,這樣當接收到請求時,映射器就可以根據請求的信息找到對應的處理器方法來處理請求。
			methods.forEach((method, mapping) -> {Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);registerHandlerMethod(handler, invocableMethod, mapping);});}

調用過程

在這里插入圖片描述

在 Spring MVC 中,RequestMappingHandlerMapping 是負責處理基于注解的控制器方法的映射。默認情況下,所有標記有 @RequestMapping 注解的控制器方法都會通過 RequestMappingHandlerMapping 進行注冊和處理。這個過程涉及到以下幾個關鍵步驟:

  1. Spring容器啟動:
  • 在應用啟動時,Spring 容器會初始化所有的單例 Bean,包括 DispatcherServlet 和相關的組件。
  1. 初始化 RequestMappingHandlerMapping:
  • RequestMappingHandlerMapping 實現了 InitializingBean 接口,因此它的 afterPropertiesSet() 方法會在所有屬性設置完成后被調用,以完成其初始化工作。
  1. 掃描控制器組件:
  • 在初始化過程中,RequestMappingHandlerMapping 會掃描 Spring 容器中的 Bean,尋找帶有 @Controller 注解的類以及帶有 @RequestMapping 注解的方法。
  1. 注冊映射關系:
  • 對于找到的控制器和方法,RequestMappingHandlerMapping 會將它們的 URL 路徑和處理方法之間的映射關系注冊到內部的映射注冊表中。
  1. 構建URL到方法的映射:
  • RequestMappingHandlerMapping 會解析這些映射信息,構建一個從 URL 到控制器方法的映射表,以便能夠快速地根據請求的 URL 找到對應的處理方法。
  1. 處理請求:
  • 當 HTTP 請求到達 DispatcherServlet 時,它會使用 RequestMappingHandlerMapping 來確定請求應該由哪個控制器方法來處理。一旦找到匹配的方法,DispatcherServlet 會使用 RequestMappingHandlerAdapter 來執行該方法。
  1. 適配器模式的應用:
  • 適配器模式在這里確保了 DispatcherServlet 能夠通過統一的 HandlerAdapter 接口來執行不同類型的處理器,而不需要了解具體的實現細節。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713416.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713416.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713416.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大街款商城項目03-微服務之間調用

目錄 RestTemplate OpenFeign 1.引入依賴open-feign 2.聲明要調用的服務和接口 3.注入FeignClient啟用 4驗證 RestTemplate 在微服務架構中&#xff0c;使用RestTemplate是一種常見的方式進行服務間的HTTP通信。以下是一個簡單的示例&#xff0c;演示如何使用RestTempla…

Android minigbm框架普法

Android minigbm框架普法 引言 假設存在這么一個場景&#xff0c;我的GPU的上層實現走的不是標準的Mesa接口&#xff0c;且GPU也沒有提專門配套的gralloc和hwcompoer實現。那么我們的Android要怎么使用到EGL和GLES庫呢&#xff0c;并且此GPU驅動是支持drm實現的&#xff0c;也有…

Galaxy生信云平臺:集合操作工具大全

Galaxy平臺上的文件稱為數據集&#xff08;Dataset&#xff09;&#xff0c;如果將多個文件組合在一起&#xff0c;則形成數據集合&#xff08;Dataset collection&#xff09;。 上傳文件后&#xff0c;可以通過工具將文件構建成數據集合。具體操作可以參考前面介紹轉錄組流程…

后臺組件體系

從今天開始進入更細粒度說明。后臺微服務是由組件構成的。平臺的開發理念是為甲方打造一個生態環境。安裝實施時為客戶安裝私倉來管理組件。開發微服務時鼓勵拆分為組件。開發新功能時&#xff0c;先看有沒有相關組件&#xff0c;有的話就在pom.xml文件&#xff08;不要問我這個…

OpenDDS中避免訂閱發布同一主題時的自環現象(適用于所有DDS)

目錄 1、摘要2、理解"自反傳輸"2、解決方案2.1、使用 DataReaderListener 進行過濾3.2、使用 Partition 進行隔離3.3、 使用不同的 Topic 總結 1、摘要 在 OpenDDS 中&#xff0c;同時訂閱并發布同一主題會導致自環現象&#xff0c;即接收到自己發送的消息。本文介紹…

Day10:基礎入門-HTTP數據包Postman構造請求方法請求頭修改狀態碼判斷

目錄 數據-方法&頭部&狀態碼 案例-文件探針 案例-登錄爆破 工具-Postman自構造使用 思維導圖 章節知識點&#xff1a; 應用架構&#xff1a;Web/APP/云應用/三方服務/負載均衡等 安全產品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墻/殺毒等 滲透命令&#xff1a;文件…

最新消息:英特爾宣布成立全新獨立運營的FPGA公司——Altera

今天&#xff0c;英特爾宣布成立全新獨立運營的FPGA公司——Altera&#xff08;2015年6月Intel以 167 億美元的價格&#xff0c;收購FPGA廠商Altera&#xff09;。首席執行官Sandra Rivera和首席運營官Shannon Poulin分享展示其在超過550億美元的市場中保持領先性的戰略規劃&am…

什么是端點安全以及如何保護端點

什么是端點安全 端點是指可以接收信號的任何設備&#xff0c;是員工使用的一種計算設備&#xff0c;用于保存公司數據或可以訪問 Internet。端點的幾個示例包括&#xff1a;服務器、工作站&#xff08;臺式機和筆記本電腦&#xff09;、移動設備、虛擬機、平板電腦、物聯網、可…

一【初識EMC】

在作為硬件行業相關從業者&#xff0c;經常接觸到EMC相關問題&#xff0c;下面來簡單介紹下EMC相關方面的知識 文章目錄 前言一、生活中的EMC現象&#xff1f;二、EMC是什么三、EMC的三要素四、EMI與EMS的評估方式1.RE2.CE3.HAR4.FLICKER5.Rs6.CS7.ESD8.EFT9.DIP10.PMS11.surge…

Zookeeper3:客戶端命令

文章目錄 客戶端命令連接服務端Zookeeper客戶端內置命令 ls - 節點信息 客戶端命令 連接服務端Zookeeper //客戶端連接服務端zookeeper 默認連的本機2181端口的zookeeper cd /opt/module/zookeeper-3.9.1/bin && sh zkCli.sh//客戶端連接遠程服務端zookeeper cd /op…

【小塵送書-第十一期】編程的基石,開發的核心:《算法秘籍》

大家好&#xff0c;我是小塵&#xff0c;歡迎你的關注&#xff01;大家可以一起交流學習&#xff01;歡迎大家在CSDN后臺私信我&#xff01;一起討論學習&#xff0c;討論如何找到滿意的工作&#xff01; &#x1f468;?&#x1f4bb;博主主頁&#xff1a;小塵要自信 &#x1…

R語言簡介|你對R語言了解多少?

R語言是一種專門用于統計計算和圖形展示的開源編程語言&#xff0c;它在數據科學領域有著廣泛的應用。下面對R語言的環境、基礎語法及注釋進行解釋&#xff1a; R語言環境 安裝與配置 安裝R語言通常可以從官方站點下載對應操作系統的安裝包&#xff0c;如Windows、Linux、ma…

lotus worker停止接單

worker停止接單 會做完當前的任務 lotus-worker set --enabledfalse# lotus-worker --worker-repo/worker01 set --enabledfalse DEPRECATED: This command will be removed in the future# lotus-worker --worker-repo/worker01 info Enabled: false參考 worker停止接單

如何使用GAP-Burp-Extension掃描潛在的參數和節點

關于GAP-Burp-Extension GAP-Burp-Extension是一款功能強大的Burp擴展&#xff0c;該工具在getAllParams擴展的基礎上進行了升級&#xff0c;該工具不僅可以幫助廣大研究人員在安全審計過程中掃描潛在的參數&#xff0c;而且還可以搜索潛在的鏈接并使用這些參數進行測試&#…

零基礎如何快速入門倫敦金交易

倫敦金交易是金融市場中備受關注的一種投資方式。對于想要學習如何炒倫敦金并快速開始交易的人來說&#xff0c;本文將為您提供一份全面而詳細的指南。無論您是初學者還是有經驗的交易者&#xff0c;本文都將幫助您了解倫敦金交易的基本知識&#xff0c;并提供一些實用的技巧和…

安卓與鴻蒙的區別

安卓和鴻蒙是兩個不同的操作系統。下面是它們的一些區別&#xff1a; 1. 公司&#xff1a;安卓是由谷歌開發的操作系統&#xff0c;而鴻蒙是由華為開發的操作系統。 2. 開放性&#xff1a;安卓是開放源代碼的操作系統&#xff0c;可以由各種手機制造商進行定制和使用。鴻蒙也…

協議-http協議-基礎概念03-http狀態碼-http特點-http性能-壓縮和分塊傳輸-范圍請求

參考來源&#xff1a; 極客時間-透視HTTP協議(作者&#xff1a;羅劍鋒)&#xff1b; 01-狀態碼分類 開頭的 Version 部分是 HTTP 協議的版本號&#xff0c;通常是HTTP/1.1&#xff0c;用處不是很大。后面的 Reason 部分是原因短語&#xff0c;是狀態碼的簡短文字描述&#xff…

04鎖機制-分布式鎖

一句話導讀 分布式鎖是一種在分布式系統中實現對共享資源的訪問控制的鎖機制&#xff0c;它可以確保在不同的節點上只有一個線程能夠獲取鎖&#xff0c;從而避免了分布式環境下的并發訪問問題 目錄 一句話導讀 一、什么是分布式鎖 二、實現分布式鎖的方式 1.基于數據庫實現…

【Redis】高級特性 - 發布和訂閱

文章目錄 1. 發布/訂閱模式概述2. 在Redis中使用發布/訂閱模式2.1 發布消息2.2 訂閱頻道2.3 接收消息 3. 示例演練3.1 啟動兩個Redis客戶端3.2 發布者發布消息3.3 訂閱者接收消息 4. 取消訂閱5. 發布/訂閱模式的優勢結語 在Redis的學習中&#xff0c;發布/訂閱&#xff08;Pub/…

每周一算法:雙向廣搜

題目鏈接 字符串變換 題目描述 已知有兩個字串 A , B A,B A,B&#xff0c;及一組字串變換的規則&#xff08;至多 6 6 6個規則&#xff09;: A 1 → B 1 A_1→B_1 A1?→B1? A 2 → B 2 A_2→B_2 A2?→B2? … 規則的含義為&#xff1a;在 A A A中的子串 A 1 A_1 A1?…