在web.xml中配置
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-beans.xml</param-value>
</context-param>
直接找到类ContextLoaderListener ,首先看下类的继承关系
public class ContextLoaderListener extends ContextLoader implements ServletContextListener
通过继承关系知道类继承自javax.servlet.ServletContextListener类。那么就可以断定Spring肯定是重写这个类的contextInitialized(ServletContextEvent event)
和contextDestroyed(ServletContextEvent event)
方法,这两个方法的本质是监听者模式的应用中的回调函数,方法中的参数都是动态传入的,但是我们不用管参数是什么时候传入的,只是重写这两个方法就可以实现我们要的操作。
当然Spring已经帮助我们实现了,而且实现的很牛逼,就是传说的IOC,读入我们自己定义的xml配置文件来实例化(预加载)我们的bean定义。详细的加载过程我们会在Spring IOC专题来说。
我们这里看一下Spring的代码对这两个方法的实现。
Spring 3.x版本的实现
/**
* Initialize the root web application context.
* <p>在得到初始的ServletContextEvent之后你可以做很多的事情,基于事件的回调是最基本要用到的模式
* ,,在得到资源和使用资源之间的一个桥梁, 这样可以默认假设已经有资源,使用资源,然后资源的提供者是真正的
* 资源产生者,在生产出资源之后,发布事件,当然事件中会封装资源,实现监听的对象调用实现的监听器中的方法,将资源传入,OK
*/
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;//就是父类,就是自己
}
//在这里就会进行Spring环境的加载,bean工厂
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
Spring 4.x 版本的实现——去除了this.contextLoader的复制操作很判断
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
具体的initWebApplicationContext
方法在父类ContextLoader中,类中有声明的成员private WebApplicationContext context;
,这个类相信大家都知道它的重要性。
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
这个方法的重要的几行代码:
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);
//上一行代码是servletContext和WebApplicationContext的桥梁,就是相互持有对方的引用,以后可以通过
//WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
//来得到环境工厂的引用
初始化web工厂的方法是configureAndRefreshWebApplicationContext
进入内部看代码(只列出重要代码)。
// Determine parent for root web application context, if any.
ApplicationContext parent = loadParentContext(sc);
wac.setParent(parent);
//这才是web和spring的连接桥梁
wac.setServletContext(sc);
String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if (initParameter != null) {
wac.setConfigLocation(initParameter);
}
customizeContext(sc, wac);
wac.refresh();
重要的代码是最后一行刷新,这个刷新的详细介绍放到Spring IOC一节分享。
好了,以上就是web.xml中ContextLoaderListener的配置说明,如有问题静等回复和讨论。