ServletContext 被 Servlet 程序用來與 Web 容器通信。例如寫日志,轉發請求。每一個 Web 應用程序含有一個Context,被Web應用內的各個程序共享。因為Context可以用來保存資源並且共享,所以我所知道的 ServletContext 的最大應用是Web緩存----把不經常更改的內容讀入內存,所以服務器響應請求的時候就不需要進行慢速的磁盤I/O了。
ServletContextListener 是 ServletContext 的監聽者,如果 ServletContext 發生變化,如服務器啟動時 ServletContext 被創建,服務器關閉時 ServletContext 將要被銷毀。
在JSP文件中,application 是 ServletContext 的實例,由JSP容器默認創建。Servlet 中調用 getServletContext()方法得到 ServletContext 的實例。
我們使用緩存的思路大概是:
-
服務器啟動時,ServletContextListener 的 contextInitialized()方法被調用,所以在里面創建好緩存。可以從文件中或者從數據庫中讀取取緩存內容生成類,用 ervletContext.setAttribute()方法將緩存類保存在 ServletContext 的實例中。
-
程序使用 ServletContext.getAttribute()讀取緩存。如果是 JSP,使用a pplication.getAttribute()。如果是 Servlet,使用 getServletContext().getAttribute()。如果緩存發生變化(如訪問計數),你可以同時更改緩存和文件/數據庫。或者你等 變化積累到一定程序再保存,也可以在下一步保存。
-
服務器將要關閉時,ServletContextListener 的 contextDestroyed()方法被調用,所以在里面保存緩存的更改。將更改后的緩存保存回文件或者數據庫,更新原來的內容。
import User; //my own class import DatabaseManager; // my own class import javax.servlet.ServletContext; import javax.servlet.ServletContextListener;public class MyContextListener
</span><span style="color: #0000ff;">implements</span><span style="color: #000000;"> ServletContextListener { </span><span style="color: #0000ff;">private</span> ServletContext context = <span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> contextInitialized(ServletContextEvent event) { context </span>=<span style="color: #000000;"> event.getServletContext(); User user </span>= DatabaseManager.getUserById(1<span style="color: #000000;">); context.setAttribute(</span>"user1"<span style="color: #000000;">, user); } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> contextDestroyed(ServletContextEvent event) { User user </span>= (User)context.getAttribute("user1"<span style="color: #000000;">); DatabaseManager.updateUserData(user); </span><span style="color: #0000ff;">this</span>.context = <span style="color: #0000ff;">null</span><span style="color: #000000;">; }
}
布署 ServletContextListener
你實現(implements)了 ServletContextListener 編譯后,把它放在正確的WEB-INF/classes目錄下,更改WEB-INF目錄下的 web.xml文件,在web-app節點里添加
<listener> <listener-class>MyServletContextListener</listener-class> </listener>
Spring中的ContextLoaderListener使用
1、在web.xml配置監聽器ContextLoaderListener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
ContextLoaderListener的作用就是啟動Web容器時,自動裝配ApplicationContext的配置信息。因為它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啟動容器時,就會默認執行它實現的方法。
2、部署applicationContext的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/applicationContext-*.xml
</param-value>
</context-param>
在<param-value> </param-value>里指定相應的xml文件名,如果有多個xml文件,可以寫在一起並一“,”號分隔。上面的applicationContext-*.xml采用通配符,比如這那個目錄下有applicationContext-ibatis-base.xml,applicationContext-action.xml,applicationContext-ibatis-dao.xml等文件,都會一同被載入。
由此可見applicationContext.xml的文件位置就可以有兩種默認實現:
第一種:直接將之放到/WEB-INF下,之在web.xml中聲明一個listener、
第二種:將之放到classpath下,但是此時要在web.xml中加入<context-param>,用它來指明你的applicationContext.xml的位置以供web容器來加載。按照Struts2 整合spring的官方給出的檔案,寫成:
<!-- Context Configuration locations for Spring XML files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
</context-param>
3、調用處
在ContextLoaderListener中關聯了ContextLoader這個類,所以整個加載配置過程由ContextLoader來完成。看看它的API說明
第一段說明ContextLoader可以由 ContextLoaderListener和ContextLoaderServlet生成。如果查看ContextLoaderServlet的API,可以看到它也關聯了ContextLoader這個類而且它實現了HttpServlet。這個接口
第二段,ContextLoader創建的是 XmlWebApplicationContext這樣一個類,它實現的接口是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->
BeanFactory這樣一來spring中的所有bean都由這個類來創建
IUploaddatafileManager uploadmanager = (IUploaddatafileManager) ContextLoaderListener.getCurrentWebApplicationContext().getBean("uploadManager");