5.
?
事件監(jiān)聽(tīng)的方法和相關(guān)的類(lèi)
事件的分類(lèi)和
Listener
接口
Servlet
事件有兩個(gè)級(jí)別:
1.
?
Application
級(jí)別事件
包含著運(yùn)行應(yīng)用程序的虛擬機(jī)級(jí)別的相關(guān)資源和狀態(tài),即和
servlet
的
Context
對(duì)象相關(guān)。
2.
?
Session
級(jí)別的事件
包含著一個(gè)單一用戶的
session
的一系列請(qǐng)求的相關(guān)資源和狀態(tài),即
Http
的
Session
對(duì)象。
在上面兩個(gè)級(jí)別的事件,又可分別分為兩種:
1.
?
生命周期的改變
2.
?
屬性的改變
你可以為上面四種事件創(chuàng)建一個(gè)或多個(gè)監(jiān)聽(tīng)類(lèi)。一個(gè)單一的監(jiān)聽(tīng)類(lèi)可以監(jiān)視多種事件。
創(chuàng)建一個(gè)事件類(lèi)可以從
javax.servlet
包或
javax.servlet.http
包中實(shí)現(xiàn)合適的接口。下表中列出了四種事件相關(guān)的接口。
事件種類(lèi)
|
事件描述
|
接口
|
Context
生命周期的改變
|
context
的建立和即將關(guān)閉
context
|
Javax.servlet.ServletContextListener
|
Context
屬性值的改變
|
添加,刪除,修改
context
的屬性值
|
Javax..servlet.ServletContextAttributeListener
|
Session
生命周期的改變
|
Session
的創(chuàng)建,注銷(xiāo),超時(shí)
|
Javax.servlet.http.HttpSessionListener
|
Session
屬性值的改變
|
添加,刪除,修改
session
的屬性值
|
Javax.servlet.htpp.HttpSessionAttributeListener
|
典型的事件監(jiān)聽(tīng)過(guò)程
考慮一個(gè)
web
應(yīng)用是由一組訪問(wèn)數(shù)據(jù)庫(kù)的
servlet
組成的。一個(gè)典型的事件監(jiān)聽(tīng)機(jī)制是這樣的,創(chuàng)建一個(gè)
context
生命周期的事件來(lái)管理數(shù)據(jù)庫(kù)連接,這個(gè)監(jiān)聽(tīng)器可以有如下的功能:
1.
?
這個(gè)監(jiān)聽(tīng)器監(jiān)視著應(yīng)用程序的啟動(dòng)
2.
?
這個(gè)應(yīng)用程序?qū)懭肴罩镜綌?shù)據(jù)庫(kù)中并且把連接對(duì)象存儲(chǔ)在
context
中
3.
?
Servelt
使用連接對(duì)象來(lái)執(zhí)行
SQL
4.
?
監(jiān)聽(tīng)器監(jiān)聽(tīng)?wèi)?yīng)用程序的即將關(guān)閉
5.
?
在關(guān)閉應(yīng)用程序之前,先關(guān)閉連接對(duì)象
事件監(jiān)聽(tīng)的聲明和調(diào)用
事件監(jiān)聽(tīng)的聲明在應(yīng)用程序的
web.xml
里,用
<listener>
元素,該元素是
<web-app>
的子元素。每個(gè)監(jiān)聽(tīng)器都對(duì)應(yīng)一個(gè)
<listener>
,有一個(gè)
<listener-class>
子元素用來(lái)指定對(duì)應(yīng)的類(lèi)名。在每種事件中,你需要指定你想調(diào)用的順序。
在應(yīng)用程序啟動(dòng)之后,并且在第一次請(qǐng)求之前,
servlet
容器會(huì)創(chuàng)建并注冊(cè)每個(gè)監(jiān)聽(tīng)類(lèi)的實(shí)例。每種事件,監(jiān)聽(tīng)器是按照他們聲明的順序來(lái)注冊(cè)的。然后,當(dāng)應(yīng)用程序開(kāi)始運(yùn)行,每種事件監(jiān)聽(tīng)器安裝他們的順序調(diào)用。在最后一次請(qǐng)求之前,所有的監(jiān)聽(tīng)器都保持活動(dòng)狀態(tài)。
一旦應(yīng)用程序關(guān)閉,
session
事件首先發(fā)生,以他們聲明的順序相反。然后
context
事件發(fā)生也是以聲明的順序相反。
下面是一個(gè)例子:
<web-app>
?? <display-name>MyListeningApplication</display-name>
?? <listener>
????? <listener-class>com.acme.MyConnectionManager</listenerclass>
?? </listener>
?? <listener>
????? <listener-class>com.acme.MyLoggingModule</listener-class>
?? </listener>
?? <servlet>
????? <display-name>RegistrationServlet</display-name>
????? ...
?? </servlet>
</web-app>
假設(shè)
MyConnectionMnanager
和
MyLoggingModule
都是實(shí)現(xiàn)
ServletContextListener
接口,
MyLoggingModule
也是實(shí)現(xiàn)了
HttpSessionListener
接口。
當(dāng)應(yīng)用程序運(yùn)行,兩個(gè)監(jiān)聽(tīng)器都會(huì)監(jiān)聽(tīng)
context
生命周期事件,
MyLoggingModule
監(jiān)聽(tīng)器還會(huì)監(jiān)聽(tīng)
session
生命周期。在
context
生命周期中,
MyConnectionMananger
會(huì)首先開(kāi)始監(jiān)聽(tīng),因?yàn)樗暶髟谇懊妗?/span>
事件監(jiān)聽(tīng)器的編碼和發(fā)布指南
請(qǐng)注意事件監(jiān)聽(tīng)器類(lèi)的以下規(guī)則和指南:
l
????????
在多線程的應(yīng)用程序中,屬性可能同時(shí)改變。這是不需要
Servlet
容器來(lái)同步結(jié)果――在這種情況下監(jiān)聽(tīng)類(lèi)本身負(fù)責(zé)保持?jǐn)?shù)據(jù)的完整性。
l
????????
每個(gè)監(jiān)聽(tīng)類(lèi)都必須有一個(gè)
public
的零參數(shù)的構(gòu)造函數(shù)。
l
????????
每個(gè)監(jiān)聽(tīng)類(lèi)文件必須打包到
WAR
文件,也可以是在
/WEB-INF/classes
或是包含在
/WEB-INF/lib
下的
JAR
文件中。
注意:在分布式的環(huán)境中,事件監(jiān)聽(tīng)類(lèi)的作用域是包含這個(gè)部署描述文件的虛擬機(jī)。不需要分布式的
Web
容器來(lái)傳遞
servlet
的
context
事件或是
session
事件到其他的虛擬機(jī)。這個(gè)在
Sun Microsystem
的
Java Servlet
規(guī)范,
2.3
版本。
事件監(jiān)聽(tīng)器的方法和相關(guān)的類(lèi)
這部分列出了事件監(jiān)聽(tīng)器的方法,當(dāng)
servlet
的
context
事件或是
servlet
的
session
事件發(fā)生時(shí),容器將會(huì)調(diào)用他們。這些方法的輸入的事件對(duì)象的類(lèi)型不一樣,因此一下討論事件類(lèi)和他們的方法。
ServletContextListener
方法,
ServletContextEvent
類(lèi)
ServletContextListener
接口規(guī)范以下的方法:
?????? void contextInitialized(ServletContextEvent sce)
????????????? servlet
容器調(diào)用這個(gè)方法來(lái)通知監(jiān)聽(tīng)器,
servlet
的
context
已經(jīng)建立并且應(yīng)用程序準(zhǔn)備處理請(qǐng)求。
?????? void contextDestory(ServletContextEvent sce)
????????????? servlet
容器調(diào)用這個(gè)方法來(lái)通知監(jiān)聽(tīng)器應(yīng)用程序即將關(guān)閉。
Servlet
容器創(chuàng)建一個(gè)
java.servlet.ServletContextEvent
對(duì)象作為調(diào)用
ServletContextListener
方法的輸入。
ServletContextEvent
類(lèi)包含以下方法,你的監(jiān)聽(tīng)器可以調(diào)用
ServletContext getServletContext()
用這個(gè)方法返回已創(chuàng)建的或是將要銷(xiāo)毀的
servlet context
對(duì)象,從中你可以得到你想要的信息。(未完待續(xù))
?