?
?
HandlerMapping是個(gè)接口,里面就只有一個(gè)方法getHandler,源碼如下:
?
spring項(xiàng)目啟動(dòng)的時(shí)候會(huì)掃描包,專(zhuān)門(mén)有個(gè)map用來(lái)存儲(chǔ)controller類(lèi)的(key是@RequestMapping里面的value),這個(gè)getHandler方法就是根據(jù)這個(gè)value找到這個(gè)類(lèi)對(duì)象。
HandlerAdapter里面有個(gè)方法handle,參數(shù)需要一個(gè)handler,返回值就是ModelAndView,model是鍵值對(duì)形式的參數(shù)啦,view就是返回的那個(gè)String,比如:/login,在SpringMVC配置文件里面不是配置了視圖解析器么,完了還配置了前綴和后綴,前綴是**/jsp/后綴是.jsp還記得么,完了萬(wàn)一找不到你寫(xiě)的那個(gè)返回視圖還會(huì)報(bào)404,這里就是原因。
?
下面來(lái)看看ViewResolver,這哥們也是個(gè)接口,里面就一個(gè)方法,resolveViewName,所以說(shuō)源碼寫(xiě)得好,光看名字就知道是干啥的,參數(shù)一個(gè)name一個(gè)locale,就是根據(jù)名字和前后綴就能找到那個(gè)jsp了,View也是個(gè)接口有很多實(shí)現(xiàn)類(lèi),配置文件里面不是要注明解析類(lèi)么,解析類(lèi)就是View的子類(lèi),找到j(luò)sp把里面的東東解析成瀏覽器能認(rèn)識(shí)的東東。
?
最后返回給DispatchServlet,這個(gè)類(lèi)自己做后面的操作,也就是渲染view再返回給瀏覽器,這里DispatchServlet類(lèi)做了一個(gè)判斷,處理返回的不是view而是其他的類(lèi)型的情況,比如移動(dòng)端請(qǐng)求一些數(shù)據(jù),如果不是view那么就沒(méi)有viewResolver什么事了,跳過(guò)它往下執(zhí)行,如果是view就會(huì)進(jìn)入到render方法中。
?
最終會(huì)執(zhí)行到AbstractView類(lèi)中的render方法,我們來(lái)看看這哥們干了啥事:
?
最后是個(gè)renderMergedOutputModel方法,這個(gè)方法的實(shí)現(xiàn)類(lèi)是AbstractView的子類(lèi),叫InternalResourceView,這個(gè)類(lèi)又調(diào)用父類(lèi)AbstractView的exposeModelAsRequestAttributes方法,這個(gè)方法就是把model注入到request的attribute中,這里你肯定要問(wèn),為嘛調(diào)來(lái)調(diào)去呢,不麻煩么,我來(lái)簡(jiǎn)單解釋一下,根據(jù)java設(shè)計(jì)理論,頂層肯定是接口,抽象類(lèi)實(shí)現(xiàn)這個(gè)接口,并可以添加一些通用的方法,這個(gè)exposeModelAsRequestAttributes就是起到這個(gè)作用。
?
最后一步,請(qǐng)看下圖:
?
forward是不是很熟悉,這不是服務(wù)端發(fā)起的請(qǐng)求么,好了,以上,就是這樣。