中文在线免费看视频_国产成人精品亚洲日本在线观看_亚洲精品第一综合99久久_国产亚洲精品日韩综合网

當(dāng)前位置: 首頁 / 技術(shù)干貨 / 正文
SpringMVC源碼解析(二)

2023-03-09

配置 contextconfiglocation 方法 dispatcherservlet 文件

  2 前端控制器DispatcherServlet

  2.1 DispatcherServlet源碼分析

  1.繼承關(guān)系分析:DispatcherServlet類-FrameworkServlet類-HttpServletBean類-HttpServlet類-GenericServlet類。

  2.先找到DispatcherServlet前端控制器類中進行請求和響應(yīng)轉(zhuǎn)發(fā)的doDispatch方法。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {
try {
ModelAndView mv = null;
Object dispatchException = null;

try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 確定當(dāng)前請求的處理程序。獲取Handler執(zhí)行鏈。
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}

HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}

if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}

this.applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}

this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}

} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}

}
}

  3.處理器執(zhí)行鏈HandlerExecutionChain處理request請求。繼續(xù)跟蹤HandlerMapping的getHandler方法。

@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
// handlerMappings是Servlet所支持的處理器映射器的集合,這里有N個處理器映射器
for (HandlerMapping mapping : this.handlerMappings) {
// 獲取處理器執(zhí)行鏈
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}

  4.繼續(xù)跟進HandlerExecutionChain getHandler(HttpServletRequest request)方法,此方法來自AbstractHandlerMapping類。

@Override
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}

// Ensure presence of cached lookupPath for interceptors and others
if (!ServletRequestPathUtils.hasCachedPath(request)) {
initLookupPath(request);
}

// 將請求request對象和處理器handler對象封裝成一個處理器執(zhí)行鏈
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) {
logger.debug("Mapped to " + executionChain.getHandler());
}

if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = getCorsConfiguration(handler, request);
if (getCorsConfigurationSource() != null) {
CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
config = (globalConfig != null ? globalConfig.combine(config) : config);
}
if (config != null) {
config.validateAllowCredentials();
}
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}

return executionChain;
}

  5.繼續(xù)跟進getHandlerExecutionChain(Object handler, HttpServletRequest request)方法。

protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
// 獲取處理器執(zhí)行鏈對象
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(request)) {
// 這里可以看出具有多個攔截器,而且攔截器是根據(jù)請求路徑做匹配的
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
// 處理器執(zhí)行鏈chain對象中最終封裝的信息為:interceptor攔截器和handler處理器
return chain;
}

  2.2 contextConfigLocation參數(shù)

  1.屬性contextConfigLocation:表示用于加載Bean的配置文件。

  2.如果沒有顯示的配置contextConfigLocation參數(shù),SpringMVC默認會去“/WEB-INF/[servlet名字]-servlet.xml”讀配置文件。默認配置文件設(shè)置可通過org.springframework.web.context.support.XmlWebApplicationContext類中的源碼來確定。、

// 根上下文的默認位置是“/WEB-INF/applicationContext.xml”,對于命名空間為“test-servlet”的上下文,則是“/WEB-INF/test-servlet.xml”(類似于servlet名稱為“test”的DispatcherServlet實例)。
@Override
protected String[] getDefaultConfigLocations() {
if (getNamespace() != null) {
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
}
else {
return new String[] {DEFAULT_CONFIG_LOCATION};
}
}

  說明:如果想查看XmlWebApplicationContext類的源碼,可以通過Idea窗口的【Navigate】-【Search Everywhere】選項,在打開的窗口中搜索對應(yīng)的類名稱即可找到類的所在位置。

  3.DispatcherServlet配置初始化參數(shù)contextConfigLocation方式見下。

<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-servlet.xml</param-value>
</init-param>
</servlet>

  4.contextConfigLocation參數(shù)可以省略不寫,但是必須保證Bean的配置文件按照“/WEB-INF/[servlet名字]-servlet.xml”規(guī)則進行定義;否則項目啟動時將找不到Bean配置文件,會報FileNotFoundException的異常。

好程序員公眾號

  • · 剖析行業(yè)發(fā)展趨勢
  • · 匯聚企業(yè)項目源碼

好程序員開班動態(tài)

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數(shù)據(jù)+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發(fā) <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數(shù)據(jù)分析 <高端班>

    開班時間:2021-07-12(北京)

    預(yù)約報名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計算開發(fā) <高端班>

    開班時間:2021-07-12(北京)

    預(yù)約報名

    開班時間:2019-07-22(北京)

    開班盛況
IT培訓(xùn)IT培訓(xùn)
在線咨詢
IT培訓(xùn)IT培訓(xùn)
試聽
IT培訓(xùn)IT培訓(xùn)
入學(xué)教程
IT培訓(xùn)IT培訓(xùn)
立即報名
IT培訓(xùn)

Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號-5 京公網(wǎng)安備 11010802035720號

中文在线免费看视频_国产成人精品亚洲日本在线观看_亚洲精品第一综合99久久_国产亚洲精品日韩综合网

            国产精品看片你懂得| 亚洲美女一区二区三区| 欧美日韩成人综合在线一区二区| 成人黄色综合网站| 国产乱码精品一品二品| 精品一区二区三区久久| 日本麻豆一区二区三区视频| 婷婷综合久久一区二区三区| 一区二区成人在线视频| 亚洲精品乱码久久久久久久久 | 免费在线看成人av| 亚洲不卡在线观看| 亚洲成av人片| 天堂在线亚洲视频| 日韩精品一二三四| 蜜臀av一级做a爰片久久| 日韩电影免费在线看| 爽好多水快深点欧美视频| 午夜成人免费视频| 日韩成人免费看| 美女任你摸久久| 日韩一区二区在线观看视频 | 另类小说视频一区二区| 56国语精品自产拍在线观看| 国产不卡视频一区二区三区| 亚洲一区二区在线视频| 久久久久久夜精品精品免费| 91免费视频观看| 久99久精品视频免费观看| 亚洲欧美日韩久久| 精品乱人伦小说| 91精品久久久久久蜜臀| 国产成人夜色高潮福利影视| 亚洲午夜av在线| 亚洲国产精品一区二区久久恐怖片 | 日韩中文字幕一区二区三区| 色综合天天综合网天天看片| 日韩不卡一区二区| 亚洲国产精品影院| 成人av资源下载| 中文字幕制服丝袜成人av| 欧美日韩一级二级三级| 欧美一区二区三区不卡| 久久久噜噜噜久噜久久综合| 国产精品久久久久天堂| 一区二区三区欧美日| 日韩av电影免费观看高清完整版在线观看| 蜜臀av国产精品久久久久| 国产馆精品极品| 色猫猫国产区一区二在线视频| 欧美日韩情趣电影| 久久久久久日产精品| 亚洲少妇屁股交4| www.亚洲色图| 欧美精品aⅴ在线视频| 精品国产精品一区二区夜夜嗨| 欧美国产激情二区三区| 曰韩精品一区二区| 久久99精品久久久| 色综合久久久久| 欧美r级在线观看| 亚洲丝袜另类动漫二区| 蜜桃一区二区三区四区| 91麻豆国产自产在线观看| 在线播放/欧美激情| 国产精品毛片大码女人| 免费在线观看不卡| 91丨九色丨蝌蚪富婆spa| 日韩视频免费观看高清完整版在线观看| 国产免费成人在线视频| 天天av天天翘天天综合网色鬼国产| 国产在线精品不卡| 欧美日本一区二区在线观看| 国产农村妇女精品| 免播放器亚洲一区| 91亚洲国产成人精品一区二三| 日韩欧美电影一区| 亚洲一二三专区| 波多野结衣的一区二区三区| 日韩欧美国产一二三区| 亚洲男人的天堂av| 国产·精品毛片| 欧美成人猛片aaaaaaa| 一区二区三区在线不卡| 成人免费毛片a| 久久午夜免费电影| 美女任你摸久久| 欧美三级电影网站| 亚洲美女免费在线| 波波电影院一区二区三区| 精品av综合导航| 麻豆久久久久久久| 欧美一级免费大片| 视频一区二区不卡| 欧洲av一区二区嗯嗯嗯啊| 久久久久久久精| 韩国女主播成人在线观看| 日韩一级成人av| 亚洲成av人片在线观看| 日本电影欧美片| 亚洲黄色尤物视频| 91蜜桃婷婷狠狠久久综合9色| 国产日韩一级二级三级| 国产精品亚洲人在线观看| 精品国产乱码久久久久久久| 日韩电影免费在线| 91精品国产综合久久久蜜臀图片| 一区二区三区在线观看视频| 色吧成人激情小说| 夜夜精品视频一区二区| 色一情一乱一乱一91av| 亚洲色图都市小说| 色天使久久综合网天天| 亚洲欧美日本韩国| 色婷婷国产精品综合在线观看| 国产精品久久久久9999吃药| 波多野结衣91| 中文字幕中文字幕一区| 91日韩一区二区三区| 亚洲欧美日韩人成在线播放| 色噜噜偷拍精品综合在线| 一区二区三区四区精品在线视频| 色天使久久综合网天天| 亚洲国产视频一区二区| 欧美精品xxxxbbbb| 精品在线免费观看| 国产欧美日韩在线看| 波多野结衣亚洲| 亚洲制服丝袜一区| 一区二区三区精品在线| 精品婷婷伊人一区三区三| 日日嗨av一区二区三区四区| 欧美一级欧美一级在线播放| 国产在线视频精品一区| 欧美国产欧美综合| 色婷婷亚洲综合| 五月激情综合网| 精品国产一二三区| 成人精品国产福利| 亚洲午夜免费福利视频| 日韩一区二区三区三四区视频在线观看| 狠狠色综合色综合网络| 亚洲欧洲三级电影| 欧美三级一区二区| 狠狠色丁香婷综合久久| 国产精品久久久久久久第一福利| 91久久一区二区| 蜜桃久久久久久久| 中文字幕一区二区三中文字幕| 97精品国产露脸对白| 国产激情视频一区二区在线观看| 亚洲午夜激情网站| 日韩美女啊v在线免费观看| 国产午夜精品福利| 久久久一区二区三区捆绑**| 欧美v日韩v国产v| 欧美一级片免费看| 91精品国产丝袜白色高跟鞋| 欧美日韩在线观看一区二区| 成人福利电影精品一区二区在线观看| 麻豆精品视频在线观看| 日本不卡免费在线视频| 日韩不卡一二三区| 天天色 色综合| 三级成人在线视频| 久久成人综合网| 国产精品99久久久久久久vr| 成人丝袜18视频在线观看| 国产精品亚洲成人| 99视频一区二区| 欧美性高清videossexo| 国产精品乱码久久久久久| 国产精品网站导航| 日韩三级高清在线| 日韩免费看的电影| 久久久精品中文字幕麻豆发布| 精品久久久久久久人人人人传媒| 亚洲人成电影网站色mp4| 欧美天堂一区二区三区| 日本不卡视频在线| 中文字幕一区在线观看| 日本一区二区三区久久久久久久久不| 欧美在线观看你懂的| 成人一二三区视频| 激情综合色播激情啊| 亚洲成av人影院在线观看网| 国产女人水真多18毛片18精品视频| 欧美猛男gaygay网站| 成人av影院在线| 久久av老司机精品网站导航| 亚洲电影第三页| 亚洲视频一区二区在线| 国产午夜精品一区二区| 欧美一区二区视频在线观看2022| 91蜜桃免费观看视频| 粉嫩蜜臀av国产精品网站| 免费在线观看视频一区| 又紧又大又爽精品一区二区| 国产精品996| 欧美精品tushy高清|