org.springframework.web.context.ContextLoaderListener
public class ContextLoaderListener
extends Object
implements ServletContextListener
作用:在启动Web容器时,自动装配Spring applicationContext.xml
的配置信息。
因为它实现了ServletContextListener
这个接口,在web.xml
配置这个监听器,启动容器时,就会默认执行它实现的方法。在ContextLoaderListener
中关联了ContextLoader
这个类,所以整个加载配置过程由ContextLoader
来完成。
ContextLoader
可以由 ContextLoaderListener
和ContextLoaderServlet
生成。ContextLoaderServlet
关联了ContextLoader
这个类而且它继承了HttpServlet
类
ContextLoader
创建的是XmlWebApplicationContext
这样一个类,它实现的接口是WebApplicationContext
->ConfigurableWebApplicationContext
->ApplicationContext
->BeanFactory
这样一来spring中的所有bean都由这个类来创建
如果在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
等文件,都会一同被载入。
例子,在web.xml
文件中加入下面代码
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
如果applicationContext.xml
文件没有在/WEB-INF/
下,或文件名不一致,或存在多个Spring配置文件,在web.xml
文件中根据下面代码修改
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml,/WEB-INF/applicationContext.xml,/WEB-INF/classes/applicationContext-*.xml
lt;/param-value>
</context-param>
spring在web中的启动是由ContextLoaderListener
开始的。ContextLoaderListener 实现了
ServlContextListener接口,并继承了``ContextLoader
类。
public class ContextLoaderListener extends ContextLoader implements ServletContextListener
1.ServletContextListener
接口有两个方法:contextInitialized
,contextDestroyed
。
在服务器加载web应用的时候,这个Listener将被调用。
spring在contextInitialized
中进行spring容器的初始化。
this.contextLoader.initWebApplicationContext(event.getServletContext());
2.ContextLoader
的initWebApplicationContext
方法:
首先判断web应用中是否有spring容器被加载过,如下
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null)
如果有被加载过,将抛出异常。提示是否放置了多个ContextLoaderListener
。
3.创建WebApplicationContext
前,将先处理父上下文(对于ERA工程而言有用可能)。
普通的web项目,是没有父上下文的。
ApplicationContext parent = loadParentContext(servletContext);
下面这句是创建WebApplicationContext
的主过程。
this.context = createWebApplicationContext(servletContext, parent);
创建完的context
置于servletContext
中,这样Spring容器的宿主就是ServletContext(application Scope)
。
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
4.createWebApplicationContext
方法:
首先进行ApplicationContext Class
的诊断:如果指定了ContextClass
但没有实现ConfigurableWebApplicationContext
的,将抛出异常。
默认将根据ContextLoader.properties
中指定class
的实例
即:org.springframework.web.context.support.XmlWebApplicationContext
之后根据Servlet的版本2.4之前及2.5的不同,获取web的DisplayName
。
设置ConfigurableWebApplicationContext
的id。
最后代码进入实质性的处理
wac.setParent(parent);
wac.setServletContext(sc);
//获取configLocation的配置
wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM));
customizeContext(sc, wac);// 用于自定义ContextClass时,扩充自定义Context