ServletContextListener

Servlet應用程序需要放置到servlet容器中運行,那麼應用程序需要與容器進行配合運行,就需要使用ServletContext 與 Web 容器通信。例如寫日誌,轉發請求等。

每一個 Web 應用程序含有一個Context,也就是ServletContext,被Web應用內的各個程序共享。因爲Context可以用來保存資源並且共享,所以我所知道的 ServletContext 的最大應用是Web緩存,用於存儲我們應用程序常用的系統參數,數據等;

那麼這個ServletContext如何被創建的呢? 如果ServletContext數據發生變更了怎麼辦呢?

ServletContextListener 此時就登場了!

ServletContextListener 是 ServletContext 的監聽者, 他會監聽ServletContext 發生的變化,如服務器啓動時通過ServletContextListener  來創建初始化ServletContext ,服務器關閉時 ServletContext 將要被銷燬也是通過ServletContextListener  對ServletContext以及存儲的數據進行銷燬。

具體如下:

  1. 服務器啓動時,ServletContextListener 的 contextInitialized()方法被調用,所以在裏面創建好緩存。可以從文件中或者從數據庫中讀取取緩存內容生成類,用 servletContext.setAttribute()方法將緩存類保存在 ServletContext 的實例中。

  2. 程序使用 ServletContext.getAttribute()讀取緩存。如果是 JSP,使用application.getAttribute()。如果是 Servlet,使用 getServletContext().getAttribute()。如果緩存發生變化(如訪問計數),你可以同時更改緩存和文件/數據庫。或者你等變化積累到一定程序再保存,也可以在下一步保存。

  3. 服務器將要關閉時,ServletContextListener 的 contextDestroyed()方法被調用,所以在裏面保存緩存的更改。將更改後的緩存保存迴文件或者數據庫,更新原來的內容。

Spring 中ServletContextListener是如何應用的?

我們知道spring項目在web容器中啓動後,容器會首先讀取web.xml配置文件,如下:

1、在web.xml配置監聽器ContextLoaderListener

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

Spring 中 ContextLoaderListener的作用就是啓動Web容器時,自動裝配ApplicationContext的配置信息。因爲它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啓動容器時,就會默認執行它實現的方法。

因此ContextLoaderListener幫助spring啓動IoC容器,也就是ContextLoaderListener自動裝配ApplicationContext的配置信息,併產生WebApplicationContext對象,然後將這個對象放置在ServletContext的屬性裏,這樣我們只要得到Servlet就可以得到WebApplicationContext對象,並利用這個對象訪問spring容器管理的bean。

2、部署spring的xml文件

如何部署applicationContext的xml文件,如果在web.xml中不寫任何參數配置信息,默認的路徑是"/WEB-INF/applicationContext.xml,在WEB-INF目錄下創建的xml文件的名稱必須是applicationContext.xml。如果是要自定義文件名可以在web.xml里加入contextConfigLocation這個context參數:

<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>  
            /WEB-INF/classes/spring-*.xml 
        </param-value>  
    </context-param>

在<param-value> </param-value>裏指定相應的xml文件名,如果有多個xml文件,可以寫在一起並一“,”號分隔。上面的spring-*.xml採用通配符,比如這那個目錄下有spring-mybatis-base.xml,spring-dao.xml等文件,都會一同被載入。

由此可見spring.xml的文件位置就可以有兩種默認實現:

第一種:直接將之放到/WEB-INF下,之在web.xml中聲明一個listener、

第二種:將之放到classpath下,但是此時要在web.xml中加入<context-param>,用它來指明你的spring.xml的位置以供web容器來加載。

以上加載spring的相關配置文件無非是將系統相關資源、數據、參數等加載到內存中,這也就是ServletContextListener完成的最終使命!

 

Spring Boot也用到了ContextLoaderListener?

目前SpringBoot已經成爲了主流的項目架構,因此就會有人疑問,SpringBoot中會不會也用到了ContextLoaderListener,但是SpringBoot是通過main主函數來啓動的,ContextLoaderListener不是需要在web.xml中配置的嗎?springboot 哪來的web.xml?

那麼我們來看看SpringBoot到底是怎麼用到的ContextLoaderListener?

@SpringBootApplication
@EnableTransactionManagement
@ServletComponentScan
@MapperScan("com.xsxx.mapper")//配置mybatis包掃描

看到上面的代碼是不是感覺知道了什麼?

沒錯!就是註解,spring boot之所以強大,我個人認爲,絕對有註解的功勞啊!

在Springboot web 應用啓動代碼中添加@ComponentScan註解,使我們的Springboot應用在啓動時能掃描到該Listener.

運行項目,我們可以springboot的啓動log看到如下log信息,即表明我們的ServletContextListener註冊成功。

 

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