http請求如何被Spring web mvc處理
怎麼了解Spring web mvc對一個請求的處理流程?
我想,最好的辦法就是自己搭建一個web工程,比如一個很簡單的tomcat項目,裏面實現最簡單的Controller, 然後啓動起來,在Controller的任何地方設置一個斷點,請求該接口,當執行到斷點處時,看看整個調用棧,就大致能發現調用棧中一次調用中所使用的所有類和方法。這就很清晰的告訴了我們spring web mvc對一個請求的處理過程。
下圖是我自己搭建的很簡單的tomcat工程,設置斷點後的調用棧:
當然這個也依賴於你的web.xml是如何配置的,下圖是我的配置:
web.xml裏需要配置一個filter和一個servlet, 其中filter和filter-mapping, servlet和servlet-mapping都是成對出現的。filter用來定義對某個請求需要怎麼預處理,filter-mapping用來過濾哪些請求需要這麼經過這個處理。servlet是對一個接收的請求如何處理,比如DispatchServlet是將一個請求派發出去,有其他線程處理,處理完之後再通過DispatchServlet將應發發送出去;servlet-mapping是接收哪些匹配路徑下的請求。
詳細分析
第一張圖紅框中的方法是關鍵方法,主要包括:
- DelegatingProxyFilter.doFilter()方法;
- DispatcherServlet.doService()方法;
- RequestMappingHandlerAdapter.handleInternal()方法和invokeHandlerMethod()方法;
- InvocableHandlerMethod.doInvoke()方法;
- 我們實現的Controller方法。
盜用一張網上的圖,顯得更直觀一些:
其實,在tomcat啓動時,它已經爲我們做了一些初始化的事情。它會將我們標註爲Controller annotation的對象逐個實例初始化,維護一個類似的<URL, Controller>的這樣一個映射,也就是上圖中的HandlerMapping。
當一個請求過來時,根據請求的URL找到匹配的Controller及其對應的具體實現方法,當然還有整個HandlerExecutionChain。
然後會去解析這個方法中的參數,根據request中的參數值,初始化方法中形參。
緊接着執行我們自己實現的Controller方法,並返回結果。
根據是否返回ModelAndView對象做相應處理,如果有就需要viewResolver來解析該對象,並生成view。最後渲染頁面並將最終的數據返回給客戶端。