使用Spring必须在web.xml中写如下配置:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
通过ContextLoaderListener加载Spring的配置文件applicationContext.xml,实例化所有单例的bean,加载完毕后将Spring的配置存储到application内置对象中,名称为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。下面通过源码大致分析下整个过程。
看看org.springframework.web.context.ContextLoaderListener这个监听器类的源码:(源码只列出其中部分)
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
private ContextLoader contextLoader;
/**
* Initialize the root web application context.
*/
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
// 省略其他部分
}
initWebApplicationContext(event.getServletContext())方法用于加载Spring的配置文件,传入的是application内置对象,加载成功后放入application对象中
进入initWebApplicationContext(event.getServletContext())方法:
在ContextLoader类中:
public WebApplicationContext initWebApplicationContext(ServletContext servletContext){
// 加载Spring的配置文件
this.context = createWebApplicationContext(servletContext, parent);
// 向servletContext中设置属性名为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值,保存的就是Spring的配置文件内容,以后需要使用Spring的配置文件时就可以通过此名字获取
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
}
再进入createWebApplicationContext(servletContext,parent)方法,
protected WebApplicationContext createWebApplicationContext(ServletContext sc, ApplicationContext parent){
Class<?> contextClass = determineContextClass(sc);
ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
// 获取在web.xml中配置文件中指定的Spring配置文件路径
wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM));
return wac;
}
这里的CONFIG_LOCATION_PARAM就是初始值是:
public static final String CONFIG_LOCATION_PARAM = “contextConfigLocation”;
这个contextConfigLocation就是在web.xml中配置的,所以就能根据配置找到Spring的配置文件applicationContext.xml。
注:这里的源码用的Spring版本可能比较低,较新版本的源码可能有些不同,但基本思想都差不多。
上面说的加载完毕后将Spring的配置存储到application内置对象中,名称为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。在程序中也是通过这个名称来Spring配置文件中的信息的,例如通过一个监听器说明:
public class TestServletContextListener implements ServletContextListener{
private ApplicationContext context = null;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent se) {
// 获得Spring的配置文件
context = WebApplicationContextUtils.getWebApplicationContext(se.getServletContext());
se.getServletContext().setAttribute("aa", ...);
}
}
看看WebApplicationContextUtils类的getWebApplicationContext(ServletContext sc)方法的源码:
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
可以看到就是通过调用getWebApplicationContext(sc,WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);方法来获取Spring配置文件的信息的。
Author:顾故
Sign:别输给曾经的自己