使用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); } </span>
再进入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:别输给曾经的自己