Spring应用在web系统中,如果web服务停止,servlet容器会触发关闭事件并通知ContextLoaderListener,ContextLoaderListener中contextDestroyed方法调用closeWebApplicationContext(event.getServletContext())销毁Spring容器;但对于非web应用项目,则需要手动去关闭Spring;
不过手动关闭Spring容器也很容易,Spring中ApplicationContext实现类大都继承AbstractApplicationContext,而AbstractApplicationContext中定义了一个
registerShutdownHook()的方法,不需要参数,只需要显示调用此方法即可,方法实现中会向jvm绑定一个系统钩子,在关闭时将执行此钩子;非web项目通常需要手工创建ApplicationContext,样例代码如下:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.context.support.AbstractApplicationContext;
public class ServerApplication {
//private static final ILog LOG = LogFactory.getLog(ServerApplication.class);
public static void main(String[] args) {
long b = System.currentTimeMillis();
//Spring启动时,会自动触发各Service启动
ApplicationContext context =
new AnnotationConfigApplicationContext(ServerApplication.class);
long e = System.currentTimeMillis();
// LOG.info("ServerApplication started successfully in "+(e-b)+"ms.");
if(context instanceof AbstractApplicationContext)
{
((AbstractApplicationContext)context).registerShutdownHook();
}
}
}
看下
registerShutdownHook实现,如下所示,会调用doClose()来关闭Spring容器。
@Override
public void registerShutdownHook() {
if (this.shutdownHook == null) {
// No shutdown hook registered yet.
this.shutdownHook = new Thread() {
@Override
public void run() {
doClose();
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}