究竟Spring在何时调用destroy-method="close" 这个方法close()呢?终于借助JavaEye找到了答案,原来如果Spring不在Web Container或是EJB Container中的时候,这个方法还是需要我们自己来调用的,具体就是调用BeanFactory的destroySingletons()方法,文档上的“自动调用”这几个字真是害我不浅呀,原来自动也是通过Web Container或是EJB Container才可以自动,具体做法就是要实现ServletContextListener这个接口,Spring中已经有具体的实现了:
 
publicclass ContextLoaderListener implements ServletContextListener { 
        private ContextLoader contextLoader; 
       
/**
        * Initialize the root web application context.
        */

        publicvoid 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(){
                returnnew ContextLoader();
        } 
       
/**
        * Return the ContextLoader used by this listener.
        */

        public ContextLoader getContextLoader(){
                return contextLoader;
        } 
       
/**
        * Close the root web application context.
        */

        publicvoid contextDestroyed(ServletContextEvent event){
                this.contextLoader.closeWebApplicationContext(event.getServletContext());
        }

}
当tomcat关闭的时候会自动调用contextDestroyed(ServletContextEvent event)这个方法。在看一下contextLoader的closeWebApplicationContext方法:
 
publicvoid 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的代码 :
 
publicvoid 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(); 看来,没有容器,我们还是需要自己来搞定这个方法的调用的 !