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测试记录