瀏覽器的請求,是如何被映射到後端服務的方法上呢?
一個請求,通過在瀏覽器上輸入了一個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或者其他派生的註解。生成請求信息。
這裡我們能看到源碼里拿到了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本篇內容就到這裡。謝謝大家。
最後求關注,求訂閱,謝謝你的閱讀!