SpringMVC - ContextLoaderListener
我們在使用SpringMVC的時候,做的第一件事情是配置**ContextLoaderListener**的監聽器,這個監聽器的作用,就是啟動web容器的時候,自動裝配ApplicationContext的配置信息,因為ContextLoaderListener實現了ServletContextListener接口,便會將ApplicationContext放置到servletContext中。
Spring - ContextLoaderListener 的源碼解讀
/**
* Initialize the root web application context
*/
@Override
public void contextInitialized(ServletContextEvent event) {
super.initWebApplicationContext(event.getServletContext());
}
/**
* Initialize Spring's web application context for the given servlet context,
*/
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
// 判斷web.xml中存在多次ContextLoader定義
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException( "....");
}
try {
if (this.context == null) {
// 初始化context (重點)
this.context = createWebApplicationContext(servletContext);
}
if (this.context instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
ApplicationContext parent = loadParentContext(servletContext);
cwac.setParent(parent);
}
configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
// 將webApplicationContext放入到ServletContext中
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
}
else if (ccl != null) {
currentContextPerThread.put(ccl, this.context);
}
return this.context;
}
catch (RuntimeException ex) {
}
}
創建contextClass
這段代碼就是創建webApplicationContext的核心,當前類的ContextLoader同樣目錄下一定會存在屬性文件:ContextLoader.properties
**org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext**
然後通過反射的機製,進行實體類的創建
protected Class<?> determineContextClass(ServletContext servletContext) {
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
if (contextClassName != null) {
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
} else {
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
}
}
整個源碼跟蹤下來,可以簡單的歸納一下:
1. webApplicationContext存在性的驗證
2. 創建webApplicationContext實例
3. 將實例記錄在ServletContext中
4. 映射當前類加載器與創建的實例到全局變量中
private static final Map currentContextPerThread = new ConcurrentHashMap<>(1);)
最後更新:2017-08-22 19:02:15
上一篇:
移動端SDK優化的特點與經驗分享
下一篇:
新時代農產品收割 ,還有3D視覺科技加入
[Android實例] android多點觸摸demo .
Java EL??????-1.JUEL??????-??????-????????????-?????????
純CSS3實現支持自定義設定的圖標
拒絕掛馬、灌水,從現在做起!(WAF篇)
移動web app開發-----application cache 離線緩存(進階)
簡單入門循環神經網絡RNN:時間序列數據的首選神經網絡
HTAP數據庫(OLTP+OLAP) - 數據庫典型架構 優缺點剖析(shard VS shared)
tns(thrift 分布式組件)介紹
Oracle 12.2新特性掌上手冊 - 第三卷 Sharding 的增強
華為N8500集群NAS係統第三次刷新SPEC測試記錄