請(qǐng)求流程圖
????1、客戶端發(fā)請(qǐng)求意乓,被spring的前段控制器DispatcherServlet捕獲
????2拆檬、DispatcherServlet請(qǐng)求URL進(jìn)行解析,得到請(qǐng)求資源標(biāo)識(shí)符(URI)屡贺。然后根據(jù)該URI蠢棱,調(diào)用HandlerMapping獲得該Handler配置的所有相關(guān)的對(duì)象(包括Handler對(duì)象以及Handler對(duì)象對(duì)應(yīng)的攔截器),最后以HandlerExecutionChain對(duì)象的形式返回甩栈;
? ? 3泻仙、DispatcherServlet 根據(jù)獲得的Handler,選擇一個(gè)合適的HandlerAdapter量没。(附注:如果成功獲得HandlerAdapter后玉转,此時(shí)將開(kāi)始執(zhí)行攔截器的preHandler(...)方法)
? ? 4、提取Request中的模型數(shù)據(jù)殴蹄,填充Handler入?yún)⒕孔ィ_(kāi)始執(zhí)行Handler(Controller)。 在填充Handler的入?yún)⑦^(guò)程中饶套,根據(jù)你的配置漩蟆,Spring將幫你做一些額外的工作:
? ? ??HttpMessageConveter: 將請(qǐng)求消息(如Json、xml等數(shù)據(jù))轉(zhuǎn)換成一個(gè)對(duì)象妓蛮,將對(duì)象轉(zhuǎn)換為指定的響應(yīng)信息
? ? ??數(shù)據(jù)轉(zhuǎn)換:對(duì)請(qǐng)求消息進(jìn)行數(shù)據(jù)轉(zhuǎn)換怠李。如String轉(zhuǎn)換成Integer、Double等
? ? ??數(shù)據(jù)根式化:對(duì)請(qǐng)求消息進(jìn)行數(shù)據(jù)格式化蛤克。 如將字符串轉(zhuǎn)換成格式化數(shù)字或格式化日期等
? ? ??數(shù)據(jù)驗(yàn)證: 驗(yàn)證數(shù)據(jù)的有效性(長(zhǎng)度捺癞、格式等),驗(yàn)證結(jié)果存儲(chǔ)到BindingResult或Error中
? ? 5构挤、執(zhí)行用戶自行編寫的業(yè)務(wù)邏輯
? ? 6髓介、Handler執(zhí)行完成后,向HandlerAdapter?返回一個(gè)ModelAndView對(duì)象筋现;
? ? 7唐础、HandlerAdapter把ModelAdnView返回給DispatcherServlet
? ? 8箱歧、DispatcherServlet把ModelAndView傳給ViewResolver,ViewResolver結(jié)合model和view來(lái)渲染視圖
? ? 9一膨、ViewResolver返回給DispatcherServlet view對(duì)象
? ? 10呀邢、DispatcherServlet,通過(guò)view對(duì)view對(duì)象渲染成視圖豹绪,
? ? 11价淌、view返回給DispatcherServlet
? ? 12、DispatcherServlet相應(yīng)給用戶
源碼分析:
首先源碼入口瞒津,因?yàn)閟pringMVC是基于servlet的蝉衣,所以我們此處可以通過(guò)web.xml查看入口代碼
找到DispatcherServlet之后,查看一下DispatcherServlet的結(jié)構(gòu)
我們可以看到其實(shí)就是一個(gè)servlet巷蚪,但是封裝了進(jìn)了spring的容器中病毡,因?yàn)楸旧硎莝ervlet,那么我們可以找一個(gè)doGet方法和doPost方法钓辆,結(jié)果在DispatcherServlet中沒(méi)找到剪验,在父類FrameworkServlet中找到了
從doService中再次跳轉(zhuǎn)到doDispatch(request, response);跳來(lái)跳去,發(fā)現(xiàn)可算找到了
再往下追源碼的意義其實(shí)不大前联,具體的實(shí)現(xiàn)無(wú)非就是一些反射代碼功戚,想了解的也可以看一下