JavaEE 下面使用Spring 时 web.xml 中ContextLoaderListener的作用及配置
1、当在web.xml下配置如下:
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
时,启动Web容器,容器会在WEB-INF/下面查找名为applicationContext.xml 的Spring 配置文件
如果没有找到就会报错:严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:341)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
..........................
此处省去部分错误
实际上Spring 中的ContextLoaderListener类实现了ServletContextListener 接口,其中有两个重要的方法分别是contextDestroyed,contextInitialized
public class ContextLoaderListener implements ServletContextListener{
private ContextLoader contextLoader;
/**
* Initialize the root web application context.
*/
//Spring框架由此启动, contextInitialized也就是监听器类的main入口函数
public void contextDestroyed(ServletContextEvent event) {
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
/**
* Create the ContextLoader to use. Can be overridden in subclasses.
* @return the new ContextLoader
*/
protected ContextLoader createContextLoader() {
return new ContextLoader();
}
/**
* Return the ContextLoader used by this listener.
* @return the current ContextLoader
*/
public ContextLoader getContextLoader() {
return this.contextLoader;
}
/**
* Close the root web application context.
*/
public void contextInitialized(ServletContextEvent event) {
if (this.contextLoader != null) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
}
}
但在很多项目中可能会把配置文件集中管理,常见位置在:classpath下面,这样的话,你要在web.xml中在配置另外一个节点名称此时便要用到
contextConfigLocation 先来看两种不同的配置方法
配置一:
- <context-param>
- <param-name>contextConfigLacation</param-name>
- <param-value>classpath:spring/*.xml</param-value>
- </cotext-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
配置二:
- <context-param>
- <param-name>contextConfigLacation</param-name>
- <param-value>classpath*:spring/*.xml</param-value>
- </cotext-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
classpath 和 classpath* 区别:
classpath:只会到你指定的class路径中查找文件;
classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找.
举个简单的例子,在我的web.xml中是这么定义的:classpath*:META-INF/spring/application-context.xml
那么在META-INF/spring这个文件夹底下的所有application-context.xml都会被加载到上下文中,这些包括META-INF/spring文件夹底下的 application-context.xml,META-INF/spring的子文件夹的application-context.xml以及jar中的application-context.xml。
如果我在web.xml中定义的是:classpath:META-INF/spring/application-context.xml
那么只有META-INF/spring底下的application-context.xml会被加载到上下文中。