SpringBoot之@Controller和@RequestMapping的實現原理

軟件編程指南 發佈 2020-08-07T03:08:12+00:00

帶著這個疑問我們來學習本篇。後端服務使用SpringBoot只使用了一個註解就提供了web服務的實現原理是什麼呢?

瀏覽器的請求,是如何被映射到後端服務的方法上呢?

一個請求,通過在瀏覽器上輸入了一個url,是如何被SpringWeb匹配到對應的方法的呢?帶著這個疑問我們來學習本篇。


後端服務使用SpringBoot只使用了一個註解就提供了web服務的實現原理是什麼呢?


帶著上面的疑問,小編通過源碼的方式帶你一看究竟吧。

為了能讓各位童鞋更好的更容易的理解。第一趴我們先來補充點知識點。


一、註解派生概念(或者說元註解)

怎麼理解怎麼記

在java體系中,類是可以被繼承,接口可以被實現。但是註解沒有這些概念,而是有一個派生的概念。舉例,註解A。被標記了在註解B頭上,那麼我們可以說註解B就是註解A的派生。下面我們舉一個例子:


  • queryBbsPostAll使用了PostMapping類進行標記是一個POST資源
  • 我們通過main方法裡面可以知道。通過反射我們能拿到Method上的PostMapping註解信息。
  • 但是看這一行AnnotatedElementUtils.hasAnnotation(queryBbsPostAll,RequestMapping.class)為什麼也是true呢?

沒錯因為PostMapping是RequestMapping的派生註解。


請記住這個小的知識點,後面的邏輯會用到。因為下面後有大量的源碼,為了方便標註,小編使用截圖的形式,在截圖上會加上注釋信息。

二、進入正題,跟進源碼解析請求Method

通過跟進源碼,我們會發現這樣一個類。AbstractHandlerMethodMapping。其實現了實現 InitializingBean接口。在當前 Bean初始化時候會執行afterPropertiesSet -> initHandlerMethods。



RequestMappingHandlerMapping解析Method上的RequestMapping信息

isHandler 方法判斷是否是web資源類。 當一個類被標記了 @Controller 或者@RequestMapping。 注意 @RestController 是@Controller的派生類。所以這裡只用判斷 @Controller 或者@RequestMapping就行了。


detectHandlerMethods方法就是真正開始解析Method的邏輯。通過解析Method上的 @RequestMapping或者其他派生的註解。生成請求信息。

注意這個請求信息裡面也是有很多邏輯的不過不是本篇討論的重點,就不說了。稍微提一下。根據規則來匹配url邏輯就在這裡面。

這裡我們能看到源碼里拿到了Method並拿到了執行這個Method的實例Bean。在這裡封裝成了HandlerMethod並註冊到了MappingRegistry中。

在註冊的過程中把RequestMapping中的路徑信息同時也放到一個urlLookup中。key是url,value是Mapping信息。


到這裡其實我們就把本篇的議題就說明清楚了。下面我們在看下SpringWeb是如何將http請求信息路由到具體的HandlerMethod的吧。

三、 最後串一下流程

看了前面的截圖,我們知道Spring是如何把這些Web資源信息給保存起來的了。然後就看是DispatcherServlet的邏輯了。

首先DispatcherServlet 是一個Servlet。Servlet相信大家都都知道就不重點說原理。 我們直接看doService -> doDispatch 方法

根據請求路徑,找到從Mapping信息,然後根據Mapping信息匹配到具體的HandlerMethod。 ok本篇內容就到這裡。謝謝大家。

最後求關注,求訂閱,謝謝你的閱讀!

關鍵字: