Spring MVC項目啓動後的執行流程:web
1.執行流程:spring
01.在web項目啓動時,加載web.xml文件,包含核心配置文件mvc
由於web.xml文件中設置了mvc的核心控制器,因此就會初始化這個控制器app
02.好比用戶的請求路徑是 localhost:8080/hellojsp
這時候會把/hello 看成請求路徑====》核心配置文件中bean的idide
03./hello 會被核心控制器攔截,去找處理器映射器(HandlerMapping)spa
04.底層先去找到合適的HandlerMapping以後返回一個處理器執行鏈(HandlerExecutionChain)code
05.處理器執行力鏈包含一個即將執行的controller和(1-N個攔截器)xml
06.根據處理器執行鏈的handler找到HandlerAdapter對象
07.HandlerAdapter根據咱們controller的類型去執行指定的方法
08.執行方法以後須要返回一個ModleAndView
Modle ==》Map
View ==》String
09.若是設置了視圖解析器,將會執行,view實際上是一個邏輯視圖名稱
沒設置視圖解析器,將會執行,前綴和後綴沒值,view務必是一個物理視圖名稱
原理圖:
01. 點擊web.xml文件中的核心控制器
02. Ctrl+o 找到對應的方法doDispatch
03. 開始分析代碼
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) HttpServletRequest processedRequest = request; //請求對象 HandlerExecutionChain mappedHandler = null; //處理器執行鏈=咱們即將執行的Controller+(1+攔截器) boolean multipartRequestParsed = false; //解析一個請求是不是文件上傳請求
04.找到下面的代碼
// Determine handler for the current request. mappedHandler = getHandler(processedRequest);
根據咱們的請求找到須要執行的Handler(Controller)
Ctrl+鼠標左鍵 點進getHandler()
發現這個方法的返回值就是一個處理器執行鏈!
05.進入getHandler以後找到下面的代碼
HandlerExecutionChain handler = hm.getHandler(request);
06. 繼續進入這裏的hm.getHandler(request)
進入以後,發現這個方法是一個接口(HandlerMapping)中的方法,沒有方法實現,因此繼續點擊實現類AbstractHandlerMapping
07. 找到下面的代碼 而且打斷點
Object handler = getHandlerInternal(request);
08. 以後發現把獲取到的處理器執行鏈給了咱們的核心控制器
// Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
點進去getHandlerAdapter()
09. 找到下面的代碼 打斷點
if (ha.supports(handler)) { return ha; }
10. 再點進去supports()
11. 發現supports()
再接口中,可是有5個實現類,springmvc默認會執行3個
可是咱們寫的HelloController間接的實現了Controller接口,因此咱們只須要在SimpleControllerHandlerAdapter中打斷點便可!
12. 把拿到的HandlerAdapter返回給了核心控制器
13. 核心控制器中有了處理器適配器,接下來就改執行真正的代碼了
// Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
14. 點進去handle
@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); }
15. 點進去handleRequest
就進入了AbstractController,咱們的HelloController就是繼承了這個類!
這個父類執行的是handleRequestInternal(request, response);
@Override protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("您已經進入了後臺的controller/action/servlet"); return new ModelAndView("/WEB-INF/welcome.jsp"); }