java中Servlet監(jiān)聽(tīng)器的工作原理及示例詳解
監(jiān)聽(tīng)器就是一個(gè)實(shí)現(xiàn)特定接口的普通java程序,這個(gè)程序?qū)iT用于監(jiān)聽(tīng)另一個(gè)java對(duì)象的方法調(diào)用或?qū)傩愿淖?,?dāng)被監(jiān)聽(tīng)對(duì)象發(fā)生上述事件后,監(jiān)聽(tīng)器某個(gè)方法將立即被執(zhí)行。
監(jiān)聽(tīng)器原理
監(jiān)聽(tīng)原理
1、存在事件源
2、提供監(jiān)聽(tīng)器
3、為事件源注冊(cè)監(jiān)聽(tīng)器
4、操作事件源,產(chǎn)生事件對(duì)象,將事件對(duì)象傳遞給監(jiān)聽(tīng)器,并且執(zhí)行監(jiān)聽(tīng)器相應(yīng)監(jiān)聽(tīng)方法
監(jiān)聽(tīng)器典型案例:監(jiān)聽(tīng)window窗口的事件監(jiān)聽(tīng)器
例如:swing開(kāi)發(fā)首先制造Frame**窗體**,窗體本身也是一個(gè)顯示空間,對(duì)窗體提供監(jiān)聽(tīng)器,監(jiān)聽(tīng)窗體方法調(diào)用或者屬性改變:
* 關(guān)閉窗體時(shí),調(diào)用windowListener 的windowclosing() , 傳遞windowEvent參數(shù),表示窗體關(guān)閉事件對(duì)象
* 事件對(duì)象操作事件源,獲得事件源狀態(tài)
自定義監(jiān)聽(tīng)器
以上內(nèi)容可以用下圖解釋:
通過(guò)person.addPersonListener(new PersonListener(){})使事件源與監(jiān)聽(tīng)器間產(chǎn)生聯(lián)系。
事件源(在事件源方法中創(chuàng)建事件對(duì)象):
監(jiān)聽(tīng)器(參數(shù)是事件對(duì)象)
事件對(duì)象(通過(guò)事件對(duì)象可以獲得事件源)
測(cè)試方法
對(duì)上的匿名類補(bǔ)充:匿名內(nèi)部類的作用是創(chuàng)建一個(gè)實(shí)現(xiàn)接口的匿名類對(duì)象,含義是創(chuàng)建一個(gè)繼承自PersonListener的匿名類的對(duì)象),通過(guò)new表達(dá)式返回的引用被自動(dòng)向上轉(zhuǎn)型為對(duì)PersonListener的引用
Servlet監(jiān)聽(tīng)器
(不需要配置,但是監(jiān)聽(tīng)器仍需要進(jìn)行注冊(cè))
在Servlet規(guī)范中定義了多種類型的監(jiān)聽(tīng)器,它們用于監(jiān)聽(tīng)的事件源分別為 ServletContext, HttpSession 和 ServletRequest 這三個(gè)域?qū)ο蟆?/p>
Servlet監(jiān)聽(tīng)器分為三大類
1、數(shù)據(jù)域?qū)ο髣?chuàng)建和銷毀監(jiān)聽(tīng)器
2、數(shù)據(jù)域?qū)ο蠛蛯傩宰兏O(jiān)聽(tīng)器
3、綁定到 HttpSession 域中的某個(gè)對(duì)象的狀態(tài)的事件監(jiān)聽(tīng)器
(一)數(shù)據(jù)域?qū)ο髣?chuàng)建銷毀監(jiān)聽(tīng)器 — 監(jiān)聽(tīng)三個(gè)與對(duì)象 (三個(gè)監(jiān)聽(tīng)器)
1、ServletContextListener : 用來(lái)監(jiān)聽(tīng)ServletContext對(duì)象的創(chuàng)建和銷毀
監(jiān)聽(tīng)創(chuàng)建
監(jiān)聽(tīng)銷毀
* ServletContext對(duì)象代表全局唯一對(duì)象,每個(gè)web工程會(huì)產(chǎn)生一個(gè)ServletContext,服務(wù)器啟動(dòng)創(chuàng)建,服務(wù)器關(guān)閉銷毀
編寫監(jiān)聽(tīng)器
步驟一:編寫類實(shí)現(xiàn)特定監(jiān)聽(tīng)器接口
步驟二:注冊(cè)監(jiān)聽(tīng)器,不是通過(guò)事件源,而是在web.xml 進(jìn)行配置
(監(jiān)聽(tīng)器和Servlet、Filter不同,不需要url配置,監(jiān)聽(tīng)器執(zhí)行不是由用戶訪問(wèn)的,監(jiān)聽(tīng)器 是由事件源自動(dòng)調(diào)用的)
servletContext域?qū)ο蠛螘r(shí)創(chuàng)建和銷毀:
- 創(chuàng)建:服務(wù)器啟動(dòng)針對(duì)每一個(gè)web應(yīng)用創(chuàng)建servletcontext
- 銷毀:服務(wù)器關(guān)閉前先關(guān)閉代表每一個(gè)web應(yīng)用的servletContext
ServletContextListener主流應(yīng)用:
第一個(gè):在服務(wù)器啟動(dòng)時(shí),對(duì)一些對(duì)象進(jìn)行初始化,并且將對(duì)象保存ServletContext數(shù)據(jù)范圍內(nèi)(因?yàn)樵诒O(jiān)聽(tīng)器內(nèi)可以獲得事件源對(duì)象) — 全局?jǐn)?shù)據(jù)
- 例如:創(chuàng)建數(shù)據(jù)庫(kù)連接池
第二個(gè):對(duì)框架進(jìn)行初始化 例如:Spring框架初始化通過(guò)ServletContextListener (因?yàn)楸O(jiān)聽(tīng)器代碼在服務(wù)器啟動(dòng)時(shí)執(zhí)行)
- Spring框架(配置文件隨服務(wù)器啟動(dòng)加載) org.springframework.web.context.ContextLoaderListener
第三個(gè):實(shí)現(xiàn)任務(wù)調(diào)度,啟動(dòng)定時(shí)程序 (Timer、TimerTask) 使一個(gè)程序,定時(shí)執(zhí)行
比如說(shuō)每天晚上十二點(diǎn)給過(guò)生日的人進(jìn)行生日祝福,中國(guó)移動(dòng)對(duì)賬戶進(jìn)行同步,會(huì)在服務(wù)器使用較少的時(shí)間,例如凌晨之類,啟動(dòng)一段程序,進(jìn)行同步
java.util.Timer 一種線程設(shè)施,用于安排以后在后臺(tái)線程中執(zhí)行的任務(wù)??砂才湃蝿?wù)執(zhí)行一次,或者定期重復(fù)執(zhí)行。
Timer提供了啟動(dòng)定時(shí)任務(wù)方法 schedule
* schedule(TimerTask task, Date firstTime, long period) 用來(lái)在指定一個(gè)時(shí)間啟動(dòng)定時(shí)器,定期循環(huán)執(zhí)行
* schedule(TimerTask task, long delay, long period) 用來(lái)在當(dāng)前時(shí)間delay多少毫秒后啟動(dòng)定時(shí)器
停止定時(shí)器,timer.cancel取消任務(wù)
2、HttpSession 數(shù)據(jù)對(duì)象創(chuàng)建和銷毀監(jiān)聽(tīng)器 —– HttpSessionListener
監(jiān)聽(tīng)Session對(duì)象創(chuàng)建
監(jiān)聽(tīng)Session對(duì)象銷毀
Session何時(shí)創(chuàng)建:request.getSession()
Session何時(shí)銷毀:關(guān)閉服務(wù)器,Session過(guò)期,session.invalidate
*Session過(guò)期時(shí)間通過(guò)web.xml配置(tomcat配置文件中),默認(rèn)時(shí)間30分鐘
配置:
HttpSession監(jiān)聽(tīng)器
現(xiàn)有如下JSP頁(yè)面:
1.jsp
2.jsp
訪問(wèn)1.jsp時(shí)會(huì)執(zhí)行監(jiān)聽(tīng)器原因:因?yàn)槿绻^察jsp的源碼,封閉式英語(yǔ)培訓(xùn)jsp會(huì)被預(yù)處理成.java代碼(在tomcat中work文件夾下,參見(jiàn)http://blog.csdn.net/megustas_jjc/article/details/53462025),我們打開(kāi)這個(gè).java代碼的源碼:
其中的getSession的實(shí)現(xiàn)實(shí)際就是request.getSession()
3、HttpServletRequest對(duì)象的創(chuàng)建和銷毀監(jiān)聽(tīng)器 —- ServletRequestListener
—-監(jiān)聽(tīng)request對(duì)象創(chuàng)建
監(jiān)聽(tīng)request對(duì)象銷毀
Request何時(shí)創(chuàng)建:請(qǐng)求發(fā)起時(shí)創(chuàng)建
Request何時(shí)銷毀:響應(yīng)結(jié)束時(shí)銷毀
例如:每次刷新界面都會(huì)創(chuàng)建銷毀一次
注意(創(chuàng)建銷毀次數(shù)由請(qǐng)求次數(shù)決定):
使用forward —- request創(chuàng)建銷毀幾次 —– 一次
使用sendRedirect —- request創(chuàng)建銷毀兩次 (兩次請(qǐng)求)
(二)ServletContext/HttpSession/ServletRequest中保存數(shù)據(jù) 創(chuàng)建、修改、移除監(jiān)聽(tīng)器
ServletContextAttributeListener 監(jiān)聽(tīng)ServletContext中屬性變化
HttpSessionAttributeListener 監(jiān)聽(tīng)HttpSession中屬性變化
ServletRequestAttributeListener 監(jiān)聽(tīng)ServletRequest中屬性變化
attributeAdded 監(jiān)聽(tīng)屬性添加 —- 當(dāng)數(shù)據(jù)范圍對(duì)象沒(méi)有該屬性,第一次添加時(shí)調(diào)用執(zhí)行
attributeRemoved 監(jiān)聽(tīng)屬性移除 —- 從一個(gè)數(shù)據(jù)范圍對(duì)象刪除一個(gè)已經(jīng)存在屬性執(zhí)行
attributeReplaced 監(jiān)聽(tīng)屬性替換 —– 當(dāng)一個(gè)數(shù)據(jù)范圍已經(jīng)存在一個(gè)屬性,向數(shù)據(jù)范圍添加相同名稱屬性觸發(fā)替換方法
例如,此處我們用HttpSessionAttributeListener舉例(ServletContextListener與ServletRequestListener同理):
JSP頁(yè)面
監(jiān)聽(tīng)器
注冊(cè)
注意:獲得返回值通過(guò)session.getAttribute(se.getName())
(三)被綁定Session對(duì)象,自我狀態(tài)感知監(jiān)聽(tīng)器
保存在 Session 域中的對(duì)象可以有多種狀態(tài):綁定到 Session 中;從 Session 域中解除綁定;隨 Session 對(duì)象持久化到一個(gè)存儲(chǔ)設(shè)備中(鈍化);隨 Session 對(duì)象從一個(gè)存儲(chǔ)設(shè)備中恢復(fù)(活化)
被存放Session的Java對(duì)象,感知自我四種狀態(tài)變化
1、被綁定
2、被解除綁定
3、被鈍化 —– 數(shù)據(jù)從內(nèi)存序列化硬盤
4、被活化 —- 數(shù)據(jù)從硬盤重新加載回內(nèi)存
HttpSessionBindingListener實(shí)現(xiàn)接口的java對(duì)象,感知自己被綁定到Session或者從Session中解除綁定
HttpSessionActivationListener實(shí)現(xiàn)接口的java對(duì)象,感知從內(nèi)存被鈍化硬盤上,雅思托福的區(qū)別從硬盤活化到內(nèi)存中
實(shí)現(xiàn)這兩個(gè)接口的類不需要 web.xml 文件中進(jìn)行注冊(cè),都是由Session自主完成的,例如在存儲(chǔ)對(duì)象的時(shí)候會(huì)自動(dòng)調(diào)用綁定
HttpSessionBindingListener
* 綁定對(duì)象方法 —-
* 解除綁定方法 —–、當(dāng)Session對(duì)象銷毀時(shí),當(dāng)中所有綁定對(duì)象解除綁定
JSP頁(yè)面:
HttpSessionActivationListener
* 感知對(duì)象被活化
* 感知對(duì)象被鈍化
使用場(chǎng)景:Session保存數(shù)據(jù),很長(zhǎng)一段時(shí)間沒(méi)用,但是不能銷毀Session對(duì)象,不想占用服務(wù)器內(nèi)存資源 —– 鈍化(將服務(wù)器內(nèi)存中數(shù)據(jù)序列化硬盤上)
JSP界面
讀取數(shù)據(jù)
注意
鈍化和活化應(yīng)該由tomcat服務(wù)器 自動(dòng)進(jìn)行 —- 配置tomcat
配置context有幾個(gè)位置?
1、tomcat/conf/context.xml 對(duì)所有虛擬主機(jī) 所有web工程生效
2、tomcat/conf/Catalina/localhost/context.xml 對(duì)當(dāng)前虛擬主機(jī)所有web工程生效
3、當(dāng)前工程/META-INF/context.xml 對(duì)當(dāng)前工程有效
鈍化后 it315目錄在哪里?在“tomcat/work/Catalina/localhost/項(xiàng)目名”目錄中
java對(duì)象如果想實(shí)現(xiàn)序列化,需要實(shí)現(xiàn)Serializable接口(因此上述Bean2實(shí)現(xiàn)Serializable接口,才可以被鈍化,并之后進(jìn)行活化并讀取)
到此這篇關(guān)于java中Servlet監(jiān)聽(tīng)器的工作原理及示例詳解的文章就介紹到這了,更多相關(guān)java Servlet監(jiān)聽(tīng)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- IntelliJ IDEA里找不到j(luò)avax.servlet的jar包的解決方法
- Servlet開(kāi)發(fā)JavaWeb工程示例詳解
- JAVA WEB中Servlet和Servlet容器的區(qū)別
- Java ServletContext對(duì)象原理及功能解析
- Java Servlet輸出中文亂碼問(wèn)題解決方案
- JavaWeb servlet實(shí)現(xiàn)下載與上傳功能的方法詳解
- Java基于ServletContextListener實(shí)現(xiàn)UDP監(jiān)聽(tīng)
- JavaWeb項(xiàng)目Servlet無(wú)法訪問(wèn)問(wèn)題解決
- 使用Java servlet實(shí)現(xiàn)自動(dòng)登錄退出功能
- Java Servlet 運(yùn)行原理分析
相關(guān)文章
Spring boot2+jpa+thymeleaf實(shí)現(xiàn)增刪改查
這篇文章主要介紹了Spring boot2+jpa+thymeleaf實(shí)現(xiàn)增刪改查,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Spring?Security實(shí)現(xiàn)分布式系統(tǒng)授權(quán)方案詳解
這篇文章主要介紹了Spring?Security實(shí)現(xiàn)分布式系統(tǒng)授權(quán),本節(jié)完成注冊(cè)中心的搭建,注冊(cè)中心采用Eureka,本文通過(guò)示例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02SpringBoot設(shè)置動(dòng)態(tài)定時(shí)任務(wù)的方法詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot設(shè)置動(dòng)態(tài)定時(shí)任務(wù)的方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定的參考價(jià)值,需要的可以參考一下2022-06-06SpringBoot環(huán)境屬性占位符解析和類型轉(zhuǎn)換方式
這篇文章主要介紹了SpringBoot環(huán)境屬性占位符解析和類型轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11解決mybatis plus報(bào)錯(cuò)com.microsoft.sqlserver.jdbc.SQLServerE
這篇文章主要介紹了解決mybatis plus報(bào)錯(cuò)com.microsoft.sqlserver.jdbc.SQLServerException:必須執(zhí)行該語(yǔ)句才能獲得結(jié)果,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05剖析Java中阻塞隊(duì)列的實(shí)現(xiàn)原理及應(yīng)用場(chǎng)景
這篇文章主要介紹了剖析Java中阻塞隊(duì)列的實(shí)現(xiàn)原理及應(yīng)用場(chǎng)景,這里也對(duì)阻塞和非阻塞隊(duì)列的不同之處進(jìn)行了對(duì)比,需要的朋友可以參考下2015-12-12SpringBoot實(shí)現(xiàn)緩存預(yù)熱的幾種常用方案
緩存預(yù)熱是指在 Spring Boot 項(xiàng)目啟動(dòng)時(shí),預(yù)先將數(shù)據(jù)加載到緩存系統(tǒng)(如 Redis)中的一種機(jī)制,本文給大家介紹了SpringBoot實(shí)現(xiàn)緩存預(yù)熱的幾種常用方案,并通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-02-02SpringBoot項(xiàng)目部署時(shí)application.yml文件的加載優(yōu)先級(jí)和啟動(dòng)腳本問(wèn)題
Spring Boot在啟動(dòng)時(shí)會(huì)根據(jù)一定的優(yōu)先級(jí)順序加載配置文件,優(yōu)先級(jí)從高到低依次是:命令行參數(shù)、Jar包外部config目錄下的配置文件、Jar包同級(jí)目錄下的配置文件、classpath下的/config目錄、classpath根路徑2024-09-09springboot實(shí)現(xiàn)小程序支付的項(xiàng)目實(shí)踐
本文主要介紹了springboot實(shí)現(xiàn)小程序支付的項(xiàng)目實(shí)踐,?可以通過(guò)調(diào)用微信支付?API?實(shí)現(xiàn)支付功能,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09