作用:在啟動Web容器時,自動裝配Spring applicationContext.xml的配置信息。
因為它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啟動容器時,就會默認執行它實現的方法。在ContextLoaderListener中關聯了ContextLoader這個類,所以整個加載配置過程由ContextLoader來完成
pring在web下的入口在配置文件web.xml的監聽器中
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring/applicationContext.xml</param-value>
</context-param>
上述是在web.xml中的配置信息。
//實現了接口ServletContextListener,也就是說他必須實現contextDestroyed, contextInitialized這兩個方法
publicclass ContextLoaderListener implements ServletContextListener{
privateContextLoader contextLoader;
/**
*Initialize the root web application context.
*/
//Spring框架由此啟動, contextInitialized也就是監聽器類的main入口函數
publicvoid contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
/**
* Createthe ContextLoader to use. Can be overridden in subclasses.
* @returnthe new ContextLoader
*/
protectedContextLoader createContextLoader() {
return new ContextLoader();
}
/**
* Returnthe ContextLoader used by this listener.
* @returnthe current ContextLoader
*/
publicContextLoader getContextLoader() {
return this.contextLoader;
}
/**
* Closethe root web application context.
*/
publicvoid contextDestroyed(ServletContextEvent event) {
if (this.contextLoader != null) {
this.contextLoader.closeWebApplicationContext(event.getServletContext());
}
}
}
總的來說這個入口非常簡單,所有實現都隱藏在ContextLoader類里,我們在下一篇的內容中討論ContextLoader,如果你不知道為什么這里是程序的入口,那么復習一下ServletContextListener接口和監聽器的相關知識吧
ServletContext 被Servlet 程序用來與 Web 容器通信。例如寫日志,轉發請求。每一個 Web 應用程序含有一個Context,被Web應用內的各個程序共享。因為Context可以用來保存資源並且共享,所以我所知道的 ServletContext 的最大應用是Web緩存----把不經常更改的內容讀入內存,所以服務器響應請求的時候就不需要進行慢速的磁盤I/O了。
ServletContextListener 是ServletContext 的監聽者,如果 ServletContext 發生變化,如服務器啟動時 ServletContext 被創建,服務器關閉時 ServletContext 將要被銷毀。
在JSP文件中,application 是 ServletContext 的實例,由JSP容器默認創建。Servlet 中調用 getServletContext()方法得到 ServletContext 的實例。
我們使用緩存的思路大概是:
1. 服務器啟動時,ServletContextListener 的contextInitialized()方法被調用,所以在里面創建好緩存。可以從文件中或者從數據庫中讀取取緩存內容生成類,用 ervletContext.setAttribute()方法將緩存類保存在ServletContext 的實例中。
2. 程序使用 ServletContext.getAttribute()讀取緩存。如果是 JSP,使用a pplication.getAttribute()。如果是 Servlet,使用 getServletContext().getAttribute()。如果緩存發生變化(如訪問計數),你可以同時更改緩存和文件/數據庫。或者你等 變化積累到一定程序再保存,也可以在下一步保存。
3. 服務器將要關閉時,ServletContextListener 的 contextDestroyed()方法被調用,所以在里面保存緩存的更改。將更改后的緩存保存回文件或者數據庫,更新原來的內容。
- import User; //my own
- classimport DatabaseManager; // my own class
- import javax.servlet.ServletContext;
- import javax.servlet.ServletContextListener;
- public class MyContextListener implements ServletContextListener {
- private ServletContext context = null;
- public void contextInitialized(ServletContextEvent event) {
- context = event.getServletContext();
- User user = DatabaseManager.getUserById(1);
- context.setAttribute("user1", user);
- }
- public void contextDestroyed(ServletContextEvent event) {
- User user = (User)context.getAttribute("user1");
- DatabaseManager.updateUserData(user);
- this.context = null;
- }
- }
import User; //my own
classimport DatabaseManager; //my own class
importjavax.servlet.ServletContext;
importjavax.servlet.ServletContextListener;
public classMyContextListener implementsServletContextListener {
private ServletContext context = null;
public voidcontextInitialized(ServletContextEvent event) {
context =event.getServletContext();
User user =DatabaseManager.getUserById(1);
context.setAttribute("user1", user);
}
public voidcontextDestroyed(ServletContextEvent event) {
User user =(User)context.getAttribute("user1");
DatabaseManager.updateUserData(user);
this.context = null;
}
}
布署 ServletContextListener
你實現(implements)了 ServletContextListener 編譯后,把它放在正確的WEB-INF/classes目錄下,更改WEB-INF目錄下的 web.xml文件,在web-app節點里添加
<listener>
<listener-class>MyServletContextListener</listener-class>
</listener>
----------------------------------------在不同的情況下獲取數據-----------------------------------------
spring task定時器類中:
實現ApplicationContextAware接口 public class a implements ServletContextAware {
-
private ServletContext servletContext;
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
} - public void b() {
- servletContext.getAttribute("uid")
-
}}
controller 類中:
ServletContext servletContext=request.getSession().getServletContext();
servletContext.getAttribute("uid");
java普通類中:
只能從controller 傳 servletContext或者仿照task類的方式