参考网址: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 ContextLoaderListener.

Looks for a "contextClass" parameter at the web.xml context-param level to specify the context class type, falling back to the default of XmlWebApplicationContext if 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中的声明:

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。

ContextLoaderListener作用详解的更多相关文章

  1. ContextLoaderListener作用详解(转)

    ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息.因为它实现了ServletContextListener这个接口,在 ...

  2. Linux(centos)系统各个目录的作用详解

    Linux(centos)系统各个目录的作用详解 文件系统的类型 LINUX有四种基本文件系统类型:普通文件.目录文件.连接文件和特殊文件,可用file命令来识别. 普通文件:如文本文件.C语言元代码 ...

  3. shell脚本中常见的一些特殊符号和作用详解

    这篇文章主要介绍了shell脚本中常见的一些特殊符号和它的作用详解,总结的很简洁,容易看懂,需要的朋友可以参考下   在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我 ...

  4. linux(CENTOS)系统各个目录的作用详解

    Linux(CentOS)系统各个目录的作用详解 文件的类型 LINUX有四种基本文件系统类型:普通文件.目录文件.连接文件和特殊文件,可用file命令来识别. 普通文件:如文本文件.C语言元代码.S ...

  5. MySQL中的主键,外键有什么作用详解

    MySQL中的主键,外键有什么作用详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 学关系型数据库的同学,尤其在学习主键和外键时会产生一定的困惑.那么今天我们就把这个困惑连根拔起 ...

  6. Python中__init__.py文件的作用详解

    转自http://www.jb51.net/article/92863.htm Python中__init__.py文件的作用详解 http://www.jb51.net/article/86580. ...

  7. jsp九大内置对象和其作用详解

    jsp九大内置对象和其作用详解 JSP中一共预先定义了9个这样的对象,分别为:request.response.session.application.out.pagecontext.config.p ...

  8. [转载]java中import作用详解

    [转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...

  9. C++中头文件与源文件的作用详解

    一.C++ 编译模式 通常,在一个 C++ 程序中,只包含两类文件―― .cpp 文件和 .h 文件.其中,.cpp 文件被称作 C++ 源文件,里面放的都是 C++ 的源代码:而 .h 文件则被称作 ...

随机推荐

  1. (转)RabbitMQ消息队列(二):”Hello, World“

    本文将使用Python(pika 0.9.8)实现从Producer到Consumer传递数据”Hello, World“. 首先复习一下上篇所学:RabbitMQ实现了AMQP定义的消息队列.它实现 ...

  2. ajax学习计划

    来自http://segmentfault.com/a/1190000004322487?utm_source=Weibo&utm_medium=shareLink&utm_campa ...

  3. setbuf

    setbuf是linux中的C函数,主要用于打开和关闭缓冲机制. setbuf函数具有打开和关闭缓冲机制.为了带缓冲进行I/O,参数buf必须指向一个长度为BUFSIZ(定义在stdio.h头文件中) ...

  4. css解决IE6、Chrome、ff 浏览器position:fixed;和闪动问题

    首先说下开发模式,刚刚开始接触,基本沿用web端开发方式,目前开发模式上没有找到的适合的,现在基本这样:1,电脑nginx配置服务器3,电脑和手机连同一个局域网,2,android root 和 ip ...

  5. Spring.Net的Ioc功能基本配置

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入.面向方面编程(AOP).数据访问抽象及ASP.NET扩展等等. Spri ...

  6. 用泛型的IEqualityComparer<T>接口去重复项

    提供者:porschev 题目:下列数据放在一个List中,当ID和Name都相同时,去掉重复数据 ID Name 1  张三 1  李三 1  小伟 1  李三  2  李四 2  李武 ----- ...

  7. IOS_设置启动图片若干问题

    在做项目时, 发现设置了LaunchImage时发现一些问题: 1. 启动图片的设置可以通过两种方法: 1) 通过在LaunchScreen里放入ImageView 并设置图片, 这种方法的好处在于不 ...

  8. easyui菜单栏的使用

    <div id="tabs" class="easyui-tabs" data-options="plain:true,fit:true,bor ...

  9. Boa练习程序2

    做一个地址簿的gui. #Boa:Frame:AddressEntry import wx def create(parent): return AddressEntry(parent) [wxID_ ...

  10. 每日一“酷”之copy

    Copy – 复制对象 作用:提供一些函数,可以使用浅副本或深副本语义复制对象. copy模块包括两个函数copy()和deepcopy(),用于复制现有的对象 1.  浅副本 copy()创建的浅副 ...