private ContextLoader contextLoader;
/**
* Initialize the root web application context.
*/
public void contextInitialized(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.
*/
public ContextLoader getContextLoader() {
return contextLoader;
}
/**
* Close the root web application context.
*/
public void contextDestroyed(ServletContextEvent event) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
}
servletContext.log("Closing root WebApplicationContext");
Object wac = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (wac instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) wac).close();
}
}
AbstractApplicationContext.Close的代码 :
logger.info("Closing application context [" + getDisplayName() + "]");
// Destroy all cached singletons in this context,
// invoking DisposableBean.destroy and/or "destroy-method".
getBeanFactory().destroySingletons();
// publish corresponding event
publishEvent(new ContextClosedEvent(this));
}
最终还是调用到了getBeanFactory().destroySingletons(); 看来,没有容器,我们还是需要自己来搞定这个方法的调用的 !
- 作者: hpq852 2004年12月28日, 星期二 18:07
举个例子,ContextLoaderListener的源代码,
我们知道,如果要在tomcat里面使用spring的话需要这个Listener(或者ContextLoaderServlet)
public class ContextLoaderListener implements ServletContextListener {
private ContextLoader contextLoader;
/**
* Initialize the root web application context.
*/
public void contextInitialized(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.
*/
public ContextLoader getContextLoader() {
return contextLoader;
}
/**
* Close the root web application context.
*/
public void contextDestroyed(ServletContextEvent event) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
}
当tomcat关闭的时候会自动调用contextDestroyed(ServletContextEvent event)这个方法。在看一下contextLoader的closeWebApplicationContext方法:
public void closeWebApplicationContext(ServletContext servletContext) throws ApplicationContextException {
servletContext.log("Closing root WebApplicationContext");
Object wac = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (wac instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) wac).close();
}
}
就应该明白文档里面是什么意思了,AbstractApplicationContext.Close这个方法是要你自己调用的,在程序要结束的时候保证调用这个close方法,在这里的话就是由Listener来保证tomcat退出的时候调用close方法。
AbstractApplicationContext.Close的代码
public void close() {
logger.info("Closing application context [" + getDisplayName() + "]");
// Destroy all cached singletons in this context,
// invoking DisposableBean.destroy and/or "destroy-method".
getBeanFactory().destroySingletons();
// publish corresponding event
publishEvent(new ContextClosedEvent(this));
}
其实就是调用context里面的beanFactory的destroySingletons()方法了,这个没什么好说的。我的意思就是,容器本身不知道什么时候要shutdown了,这个消息是要靠外部(程序员)来提供的。