Spring MVC:Web環境下的SpringMVC:SpringMVC提供了可插拔的框架嵌入形式,只需要修改配置文件就可以在Web項目中插入或卸載SpirngMVC。
配置前端控制器。SpringMVC的入口程序是壹個全局Servlet,它截取指定的壹組請求,交給SpringMVC框架進行後續處理操作。Web.xml中配置了以下字段
【java】?觀平原?復制
& lt!- ?SpingMVC前端控制器?-& gt;
& ltservlet & gt
& ltservlet-name & gt;調度員& lt/servlet-name & gt;
& ltservlet-class & gt;org . spring framework . web . servlet . dispatcher servlet & lt;/servlet-class & gt;
& lt!- ?配置SpringMVC的IOC容器?-& gt;
& ltinit-param >
& ltparam-name & gt;contextConfigLocation & lt/param-name & gt;
& lt參數值& gt/we b-INF/root-context . XML & lt;/param-value & gt;
& lt/init-param & gt;
& lt啟動時加載& gt1 & lt;/load-on-startup & gt;
& lt/servlet & gt;
& lt!- ?配置為阻止所有請求?-& gt;
& ltservlet映射& gt
& ltservlet-name & gt;調度員& lt/servlet-name & gt;
& lturl模式& gt/& lt;/URL-pattern & gt;
& lt/servlet-mapping & gt;& lt/span>。& lt/span>。
創建SpringMVC IOC容器的配置文件root-context.xml,並在/WEB-INF/中定義視圖解析器
【java】?觀平原?復制
& lt!- ?配置自動掃描包?-& gt;
& lt上下文:組件掃描?base-package="cn.com.xiaofen "?/& gt;
& lt!- ?定義視圖解析器?-& gt;
& lt豆
class = " org . spring framework . web . servlet . view . internalresourceviewresolver " & gt;
& lt財產?name="prefix "?value = "/we b-INF/view/" & gt;& lt/property & gt;
& lt財產?name= "後綴"?值= "。jsp " & gt& lt/property & gt;
& lt/bean & gt;
& lt!- ?& ltmvc:默認-servlet-handler?/& gt;& ltmvc:註釋驅動?/& gt;?-& gt;& lt/span>。& lt/span>。
定義控制器,在SpringMVC中定義方法響應客戶端請求,內存開銷更少,效率更高。
【java】?觀平原?復制
@控制器
@RequestMapping("/T ")
公共?班級?t?{
@RequestMapping("/t_1 ")
公共?字符串?t_1()?{
system . out . println(" t _ 1 ");
回歸?”索引”;
}
}
定義視圖,根據實際的視圖解析器完成相關視圖的配置。當前配置視圖應該在/WEB-INF/view/?並且文件類型是jsp文件,具體來說,應該在這個目錄下新建壹個名為index的JSP文件名。
SpringMVC處理請求的工作流程:DispatcherServlet作為SpringMVC框架的入口程序,負責調度SpringMVC框架來響應用戶的請求,如下圖所示,SpingMVC大概需要經過以下調度流程來宏觀處理壹個請求。
請求條目被前端控制器(DispatcherServlet)截獲。
前端控制器分析該請求,並將該請求委托給特定的控制器進行處理。
控制器處理請求並返回到邏輯模型。
前端控制器獲取邏輯視圖對象,調度視圖解析器,解析視圖模板響應用戶。
返回前端控制器。
SpringMVC請求流程(源代碼分析部分):從DispatcherServlet的doService()方法開始,下面只列出核心代碼和後面的代碼,並保證時序。
DispatcherServlet?調用doDispatch來處理請求。
【java】?觀平原?復制
試試?{
/*邏輯視圖和上面提到的模型*/
ModelAndView?mv?=?null
例外?dispatch異常?=?null
試試?{
/*文件上傳預處理*/
已處理請求?=?checkMultipart(請求);
multipartRequestParsed?=?(processedRequest?!=?請求);
/*確定當前請求的處理器*/
mappedHandler?=?getHandler(已處理請求);
/*找不到請求的資源*/
如果?(mappedHandler?==?null?||?mappedHandler.getHandler()?==?null)?{
noHandlerFound(processed request,回應);
返回;
}
/*確定當前請求的處理器適配器*/
HandlerAdapter?哈?=?gethandler adapter(mapped handler . gethandler());
// ...............
/*攔截器在調度之前請求應用程序*/
如果?(!mapped handler . applyprehandle(processed request,回應))?{
返回;
}
/*調用處理程序*/
mv?=?ha.handle(processedRequest,?回應,?mapped handler . gethandler());
// ......
/*調度後請求應用程序的攔截器*/
mapped handler . applyposthandle(processed request,回應,?mv);
}
接住?(例外?ex)?{
dispatch異常?=?ex;
}
/*解析視圖並響應用戶*/
processDispatchResult(processed request,?回應,?mappedHandler,?mv,?dispatch異常);
}
了解HandlerMapper,HandlerMapper表示從請求到處理對象的映射,是根據請求-響應關系創建的。getHandler方法的源代碼分析如下。
【java】?觀平原?復制
受保護?HandlerExecutionChain?getHandler(HttpServletRequest?請求)?摔投?例外?{
遍歷以找到滿足條件的HandlerMapping。
為了什麽?(HandlerMapping?嗯?:?this.handlerMappings)?{
如果?(logger.isTraceEnabled())?{
logger.trace(
“測試?漢德勒?地圖?["?+?嗯?+?"]?在?DispatcherServlet?用什麽?名字?'"?+?getServletName()?+?"'");
}
HandlerExecutionChain?漢德勒?=?hm.getHandler(請求);
如果?(漢德勒?!=?null)?{
存在
回歸?處理者;
}
}
不存在的
回歸?null
}
了解handlerAapter,SpringMVC Spring MVC,實際的請求處理函數是通過handlerAapter的Handler方法調用的。getHandlerAapter的部分源代碼如下。
【java】?觀平原?復制
受保護?HandlerAdapter?getHandlerAdapter(對象?經手人)?摔投?ServletException?{
為了什麽?(HandlerAdapter?哈?:?this.handlerAdapters)?{
如果?(logger.isTraceEnabled())?{
logger.trace("測試?漢德勒?適配器?["?+?哈?+?"]");
}
您支持處理當前的HandlerMapper嗎?
如果?(ha.supports(handler))?{
回歸?哈;
}
}
當前HandlerMapper不能作為異常處理。
扔?新的?ServletException("No?適配器?為了什麽?漢德勒?["?+?漢德勒?+
"]:?那個?DispatcherServlet?配置?需求?去哪?包括?答?HandlerAdapter?那個?支持?這個?handler”);
}
模型到視圖,SpringMVC中的ModelAndView保留了邏輯視圖和真實視圖的關系,為用戶確定了當前請求返回的視圖。processDispatchResult的源代碼分析如下。
【java】?觀平原?復制
私人?作廢?processDispatchResult(http servlet request?請求,?HttpServletResponse?回應,
HandlerExecutionChain?mappedHandler,?ModelAndView?mv,?例外?例外)?摔投?例外?{
布爾?錯誤視圖?=?假的;
/*處理異常信息*/
如果?(例外?!=?null)?{
如果?(例外?instanceof?ModelAndViewDefiningException)?{
logger . debug(" ModelAndViewDefiningException?遇到“,?例外);
mv?=?((ModelAndViewDefiningException)?例外)。getModelAndView();
}
不然呢?{
對象?漢德勒?=?(mappedHandler?!=?null?mappedHandler.getHandler()?:?null);
mv?=?processHandlerException(請求,回應,?漢德勒?例外);
錯誤視圖?=?(mv?!=?null);
}
}
/*呈現視圖並返回響應*/
如果?(mv?!=?null?& amp& amp?!mv.wasCleared())?{
渲染(mv,?請求,?回應);
如果?(errorView)?{
webutils . clearerrorrequestattributes(請求);
}
}
不然呢?{
如果?(logger.isDebugEnabled())?{
logger.debug("Null?ModelAndView?退回來了?去哪?DispatcherServlet?用什麽?名字?'"?+?getServletName()?+
"':?假設?HandlerAdapter?已完成?請求?處理”);
}
}
} ?