ContextLoaderListener作用详解
2015-09-14 00:13
465 查看
参考网址:http://blog.csdn.net/ysughw/article/details/8992322
ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。至于ApplicationContext.xml这个配置文件部署在哪,如何配置多个xml文件,现在的方法就是查看它的API文档。在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。看看它的API说明。
类ContextLoader api原文:
Performs the actual initialization work for the root application context. Called by
Looks for a
Processes a
第一段说明ContextLoader的作用--它为初始化工作装配请求上下文,这是由于调用ContextLoaderListener触发的。
第二段,ContextLoader将在web.xml寻找
由于ContextLoader的默认上下文是XmlWebApplicationContext,在XmlWebApplicationContext中的声明:
由此可见applicationContext.xml的文件位置就可以有两种默认实现:
第一种:直接将之放到/WEB-INF下,之在web.xml中声明一个listener;
第二种:将之放到classpath下,但是此时要在web.xml中加入<context-param>,用它来指明你的applicationContext.xml的位置以供web容器来加载。按照Struts2 整合spring的官方给出的档案,写成:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
</context-param>
附:从源码解析ContextLoaderListener、ContextLoader的主要作用
ContextLoaderListener源码
ContextLoader源码
从上面的源码可以得知:类ContextLoaderListener主要的作用是初始化上下文WebApplicationContext(接口)的实现类:org.springframework.web.context.support.XmlWebApplicationContext。
此外,在类ContextLoader中,方法configureAndRefreshWebApplicationContext用于部署contextConfigLocation。
ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。至于ApplicationContext.xml这个配置文件部署在哪,如何配置多个xml文件,现在的方法就是查看它的API文档。在ContextLoaderListener中关联了ContextLoader这个类,所以整个加载配置过程由ContextLoader来完成。看看它的API说明。
类ContextLoader api原文:
Performs the actual initialization work for the root application context. Called by
ContextLoaderListener.
Looks for a
"contextClass"parameter at the
web.xmlcontext-param level to specify the context class type, falling back to the default of
XmlWebApplicationContextif not found. With the default ContextLoader implementation, any context class specified needs to implement the ConfigurableWebApplicationContext interface.
Processes a
"contextConfigLocation"context-param and passes its value to the context instance, parsing it into potentially multiple file paths which can be separated by any number of commas and spaces, e.g. "WEB-INF/applicationContext1.xml, WEB-INF/applicationContext2.xml". Ant-style path patterns are supported as well, e.g. "WEB-INF/*Context.xml,WEB-INF/spring*.xml" or "WEB-INF/**/*Context.xml". If not explicitly specified, the context implementation is supposed to use a default location (with XmlWebApplicationContext: "/WEB-INF/applicationContext.xml").
第一段说明ContextLoader的作用--它为初始化工作装配请求上下文,这是由于调用ContextLoaderListener触发的。
第二段,ContextLoader将在web.xml寻找
contextClass参数,它是上下文的class类型,默认的是XmlWebApplicationContext。
第三段,讲如何部署applicationContext的xml文件。
如果在web.xml中不写任何参数配置信息,默认的路径是/WEB-INF/applicationContext.xml,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml;
如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/classes/applicationContext-*.xml
</param-value>
</context-param>
在<param-value> </param-value>里指定相应的xml文件名,如果有多个xml文件,可以写在一起并一“,”号分隔。上面的applicationContext-*.xml采用通配符,比如这那个目录下有applicationContext-ibatis-base.xml,applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件,都会一同被载入。
相应源码:
在类ContextLoader中的声明:
[code]public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
由于ContextLoader的默认上下文是XmlWebApplicationContext,在XmlWebApplicationContext中的声明:
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
由此可见applicationContext.xml的文件位置就可以有两种默认实现:
第一种:直接将之放到/WEB-INF下,之在web.xml中声明一个listener;
第二种:将之放到classpath下,但是此时要在web.xml中加入<context-param>,用它来指明你的applicationContext.xml的位置以供web容器来加载。按照Struts2 整合spring的官方给出的档案,写成:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
</context-param>
附:从源码解析ContextLoaderListener、ContextLoader的主要作用
ContextLoaderListener源码
public class ContextLoaderListener extends ContextLoader implements ServletContextListener { private ContextLoader contextLoader; ..... //初始化上下文 public void contextInitialized(ServletContextEvent event) { this.contextLoader = createContextLoader(); if (this.contextLoader == null) { this.contextLoader = this; } //调用父类的initWebApplicationContext方法 this.contextLoader.initWebApplicationContext(event.getServletContext()); } }
ContextLoader源码
public class ContextLoader { public static final String CONTEXT_CLASS_PARAM = "contextClass"; public static final String CONTEXT_ID_PARAM = "contextId"; public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses"; public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation"; public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector"; public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey"; private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties"; private static final Properties defaultStrategies; private static final Map<ClassLoader, WebApplicationContext> currentContextPerThread; private static volatile WebApplicationContext currentContext; private WebApplicationContext context; private BeanFactoryReference parentContextRef; //加载ContextLoader.properties static { try { ClassPathResource resource = new ClassPathResource( "ContextLoader.properties", ContextLoader.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException( "Could not load 'ContextLoader.properties': " + ex.getMessage()); } currentContextPerThread = new ConcurrentHashMap(1); } ...... //初始化WebApplicationContext public WebApplicationContext initWebApplicationContext( ServletContext servletContext) { if (servletContext .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { throw new IllegalStateException( "Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!"); } Log logger = LogFactory.getLog(ContextLoader.class); servletContext.log("Initializing Spring root WebApplicationContext"); if (logger.isInfoEnabled()) { logger.info("Root WebApplicationContext: initialization started"); } long startTime = System.currentTimeMillis(); try { //如果WebApplicationContext为空,则创建。 if (this.context == null) { this.context = createWebApplicationContext(servletContext); } if (this.context instanceof ConfigurableWebApplicationContext) { configureAndRefreshWebApplicationContext( (ConfigurableWebApplicationContext) this.context, 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); } if (logger.isDebugEnabled()) { logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); } if (logger.isInfoEnabled()) { long elapsedTime = System.currentTimeMillis() - startTime; logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); } return this.context; } catch (RuntimeException ex) { logger.error("Context initialization failed", ex); servletContext .setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); throw ex; } catch (Error err) { logger.error("Context initialization failed", err); servletContext .setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err); throw err; } } //创建WebApplicationContext protected WebApplicationContext createWebApplicationContext( ServletContext sc) { Class contextClass = determineContextClass(sc); if (!(ConfigurableWebApplicationContext.class .isAssignableFrom(contextClass))) { throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]"); } ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils .instantiateClass(contextClass); return wac; } ...... //配置、刷新WebApplicationContext protected void configureAndRefreshWebApplicationContext( ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { String idParam = sc.getInitParameter("contextId"); if (idParam != null) { wac.setId(idParam); } else if ((sc.getMajorVersion() == 2) && (sc.getMinorVersion() < 5)) { wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc .getServletContextName())); } else { wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } ApplicationContext parent = loadParentContext(sc); wac.setParent(parent); wac.setServletContext(sc); String initParameter = sc.getInitParameter("contextConfigLocation"); if (initParameter != null) { wac.setConfigLocation(initParameter); } customizeContext(sc, wac); wac.refresh(); } //确认上下文class类型 protected Class<?> determineContextClass(ServletContext servletContext) { String contextClassName = servletContext .getInitParameter("contextClass"); if (contextClassName != null) { try { return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load custom context class [" + contextClassName + "]", ex); } } //contextClassName默认值:org.springframework.web.context.support.XmlWebApplicationContext contextClassName = defaultStrategies .getProperty(WebApplicationContext.class.getName()); try { return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load default context class [" + contextClassName + "]", ex); } } ...... }
ContextLoader.properties
# Default WebApplicationContext implementation class for ContextLoader. # Used as fallback when no explicit context implementation has been specified as context-param. # Not meant to be customized by application developers. org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
从上面的源码可以得知:类ContextLoaderListener主要的作用是初始化上下文WebApplicationContext(接口)的实现类:org.springframework.web.context.support.XmlWebApplicationContext。
此外,在类ContextLoader中,方法configureAndRefreshWebApplicationContext用于部署contextConfigLocation。
相关文章推荐
- C# readnodefile()不能读取带有文件名为汉字的osg文件解决方法
- Lucas定理+中国剩余定理 hdu5446 Unknown Treasure
- .NET基础拾遗(2)面向对象的实现和异常的处理基础
- jq 判断多个 checkbox 选中
- 想搞个快速排序,却用上了ArrayList是不是有点“邪魔外道” ……
- android-service
- iOS 网易彩票-6设置模块三(常用小功能)
- Path和classpath
- [LeetCode#244] Shortest Word Distance II
- JNI调用
- spark 最新版1.0本地模式安装_spark入门学习一
- Lintcode搜索区间
- php服务器版本更新工具up2server
- Unity3D笔记第十三天——关节、布料
- 网络操作系统和分布式操作系统的区别
- Linux中批量删除redis中的key
- [知其然不知其所以然-5] 为什么我的风扇温度很低却转不停/或者温度很高却根本不转?
- 深入浅出:进程、线程、协程、同步、异步、回调(转载)
- Google Hacking
- pptpd免radius限速、限连接+自由定制功能脚本