天天看點

Spring-web源碼解析之ContextLoaderListener

基于版本4.1.7.RELEASE

該類作用:ContextLoaderListener作為啟動時的監聽器,用于開啟和關閉Spring的根WebApplicationContext,該監聽器在web.xml中應該放置于org.springframework.web.util.Log4jConfigListener 後面

先看看它的父類和實作的接口 

繼承ContextLoader : 應用上下文初始化的實際執行者

實作ServletContextListener :  接收ServletContext生命周期變化時的通知

構造函數:

在web.xml中如下方式定義ContextLoaderListener的時候會被預設調用:

在建立ContextLoaderListener的時候,會根據servlet中指定的contextClass和contextConfigLocation來建立web application context,具體的工作則是在ContextLoader中進行

建立的ApplicationContext會被挂到WebApplicationContext的ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性上。

帶參數的構造函數:

指定WebApplicationContext,同樣它也會被挂到ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性上。

傳入的context是否加載完成配置檔案,即是否被refresh的狀态是未定的,如果 context是ConfigurableWebApplicationContext類型并且未被refresh,則會根據狀态産生以下5種行為。

根據是否具有id,指派一個id。

ServletContext和ServletConfig會被委派給context進行代理。

調用customizeContexxt方法

通過contextInitializerClasses指定的任意ApplicationContextInitializer會被接受

調用refresh方法

如果不滿足上述行為産生的條件,則預設為使用者已經完成所需要做的工作。

實作ServletContextListener中的方法,屬于ServletContext的生命周期中開始初始化時通知的事件,我們檢視ServletContextListener中對于該方法的解釋:

意思是在web application 初始化程序開始的時候會接收到通知,但是方法名是contextInitialized過去式,那到底是開始初始化的時候通知還是初始化完畢再通知呢?我們看對于參數的解釋

參數中包含已經被初始化完畢的ServletContext,表示接收通知時,web application 應該是被初始化完畢了。所有的servlet和filter是在該通知發出後才被初始化的

回到@Override這裡調用了ContextLoader的initWebApplicationContext方法,表明在WebApplicationContext初始化完畢後才開始RootApplicationContext的初始化工作。

同樣是實作ServletContextListener中的方法,在ServletContextListener的接口方法定義中,該方法是ServletContext關閉時通知的,在任何一個listener被通知到之前,所有的servlets和filters會被銷毀,參數event中含有已經被銷毀的ServletContext。

回到@Override方法中,這裡調用了ContextLoader的closeWebApplicationContext方法,并且調用了ContextCleanupListener的cleanupAttributes清理方法,這裡面會查找到所有org.springframework開頭的類,進行各自定義的銷毀流程。