Spring-web源碼解析之ContextLoaderListener

基於版本4.1.7.RELEASE

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

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

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

實現ServletContextListener :  接收ServletContext生命週期變化時的通知

構造函數:

public ContextLoaderListener() {
}

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

<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>  

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

創建的ApplicationContext會被掛到WebApplicationContext的ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性上。

帶參數的構造函數:

public ContextLoaderListener(WebApplicationContext context) {
   super(context);
}

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

傳入的context是否加載完成配置文件,即是否被refresh的狀態是未定的,如果 context是ConfigurableWebApplicationContext類型並且未被refresh,則會根據狀態產生以下5種行爲。

  1. 根據是否具有id,賦值一個id。
  2. ServletContext和ServletConfig會被委派給context進行代理。
  3. 調用customizeContexxt方法
  4. 通過contextInitializerClasses指定的任意ApplicationContextInitializer會被接受
  5. 調用refresh方法

如果不滿足上述行爲產生的條件,則默認爲用戶已經完成所需要做的工作。

@Override
public void contextInitialized(ServletContextEvent event) {
   initWebApplicationContext(event.getServletContext());
}

實現ServletContextListener中的方法,屬於ServletContext的生命週期中開始初始化時通知的事件,我們查看ServletContextListener中對於該方法的解釋:

/**
 * Receives notification that the web application initialization
 * process is starting.
 */

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

/**
* @param sce the ServletContextEvent containing the ServletContext
* that is being initialized
*/

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

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

@Override
public void contextDestroyed(ServletContextEvent event) {
   closeWebApplicationContext(event.getServletContext());
   ContextCleanupListener.cleanupAttributes(event.getServletContext());
}

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

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












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章