spring的启动和关闭是通过在web.xml中注册启动监听器org.springframework.web.context.ContextLoaderListener来实现的,该类实现了接口javax.servlet.ServletContextListener。伴随web容器的启动和关闭,管理Spring的根org.springframework.web.context.WebApplicationContext。
该类本身并没有实现太多的代码,只是一个到org.springframework.web.context.ContextLoader和org.springframework.web.context.ContextCleanupListener的简单代理。
如果在web.xml中配置了org.springframework.web.util.Log4jConfigListener,则该监听器必须配置在它的后面。在spring3.1之后,如果在Servlet 3.0以上环境,ContextLoaderListener支持通过ContextLoaderListener(WebApplicationContext)构造器,以编码的方式来注入web应用的根上下文,而不用再在web.xml中进行配置。
当ContextLoaderListener在进行实例化的时候,会读取web.xml中配置的两个context-param参数:“contextClass“、“contextConfigLocation”。
ContextLoaderListener实例化之后,将会被注册到ServletContext的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE属性上。
在Servlet3.0+环境中,使用ContextLoaderListener(WebApplicationContext)构造器,以编码的方式(非web.xml配置方式)通过javax.servlet.ServletContext.addListener接口注册该实例,如果context实例同时满足:实现ConfigurableWebApplicationContext接口、尚未刷新,将会产生以下操作:
- 如果context还没有id,将通过setId接口赋予id;
- ServletContext、ServletConfig将被代理到context;
- customizeContext方法将被调用;
- 所有通过contextInitializerClasses初始化参数配置的 ApplicationContextInitializer接口实现都将被应用;
- 调用refresh接口;
如果context实例已经刷新或者没有实现ConfigurableWebApplicationContext接口,以上操作不会自动发生,需要用户根据自己的需用自行调用。