309
京東網上商城
SpringMVC 第二章 - WebApplicationContext的初始化
上一篇章主要總結了SpringMVC在啟動的時候,會去構造webApplicationContext對象,並且將該對象放入到ServletContext中,在web的整個生命周期中使用。在分析Spring MVC最重要的一個類DispatcherServlet的時候,在其父類初始化的時候,發現了webApplicationContext的初始化的方法,因此在這邊總結一下。
/**
* webApplicationContext的初始化
*/
protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
// Step1 : 通過構造函數的注入進行初始化
if (this.webApplicationContext != null) {
wac = this.webApplicationContext;
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
configureAndRefreshWebApplicationContext(cwac);
}
}
}
// Step2: 通過contextAttribute進行初始化
if (wac == null) {
wac = findWebApplicationContext();
}
// Step3: 重新創建webApplicationContext實例
if (wac == null) {
wac = createWebApplicationContext(rootContext);
}
if (!this.refreshEventReceived) {
onRefresh(wac);
}
if (this.publishContext) {
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
}
return wac;
}
上麵這份源碼無非是在說明webApplicationContext是如何被構造的,默認還是使用反射的方式構建xmlWebApplicationContext實體類
無論是通過構造函數注入還是單獨創建,到最後都會對已經創建的webApplicationContext實例進行配置以及刷新
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context); # 上傳
initLocaleResolver(context); # 國際化語言
initThemeResolver(context); # 頁麵主題(靜態文件)
initHandlerMappings(context); # 初始化HandlerMappings (負責請求關係的轉發)
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
我這邊隻對比較感興趣的initHandlerMappings(context) 和 initHandlerAdapters(context) 做解讀。
initHandlerMappings(context)
當客戶端發出Request時,DispatcherServlet會將Request提交給HandlerMapping,然後HandlerMapping根據WebApplicationContext的配置來回傳給DispatcherServlet相應的Controller
默認情況下,SpringMVC會加載當前係統中所有實現了HandlerMapping接口的Bean
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
} else {
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
} catch (NoSuchBeanDefinitionException ex) {
}
}
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
}
}
initHandlerAdapters(context) 這個方法與上麵的方法類似,獲取適配器,Spring默認配置了3個適配器
(1)http請求處理器適配器:HttpRequestHandlerAdapter
(2)簡單控製器處理器適配器:SimpleControllerHandlerAdapter
(3)注解方法處理器適配器:AnnotationMethodHandlerAdapter
最後更新:2017-08-22 23:32:47