所謂監(jiān)聽器就是一個java類,用來監(jiān)聽其他java類的狀態(tài)變化。
監(jiān)聽器的術語:
事件源:指被監(jiān)聽的對象(汽車)
監(jiān)聽器:監(jiān)聽的對象(報警器)
事件源與監(jiān)聽器的綁定:(就是在汽車上安裝報警器)
事件:事件源的改變(踹汽車一腳)--事件是用來獲得事件源的。
監(jiān)聽器的用途:
一:用來監(jiān)聽其他對象的狀態(tài)變化;
二:主要應用在圖形化界面中比較多;
GUI、Android
1 package test;
2 import java.awt.event.WindowEvent;
3 import java.awt.event.WindowListener;
4 import javax.swing.JFrame;
5 public class MyFrame
extends JFrame {
6 public static void main(String[] args) {
7 //創(chuàng)建一個窗口對象(事件源)
8 MyFrame mf =
new MyFrame();
9 //設置窗口的大小
10 mf.setBounds(0, 0, 200, 200
);
11 //設置窗口時顯示的
12 mf.setVisible(
true);
13 //給這個窗口設置監(jiān)聽器(事件源和監(jiān)聽器的綁定)
14 mf.addWindowListener(
new MyWindowListener());
15 }
16 }
17 /**
18 * 監(jiān)聽器
19 */
20 class MyWindowListener
implements WindowListener{
21 @Override
22 public void windowOpened(WindowEvent e) {
23 }
24 //當關閉窗口的時候觸發(fā)(改變事件源)
25 @Override
26 public void windowClosing(WindowEvent e) {
27 System.out.println("窗口正在關閉。。。"
);
28 System.exit(0);
//關閉程序
29 }
30 @Override
31 public void windowClosed(WindowEvent e) {
32 }
33 @Override
34 public void windowIconified(WindowEvent e) {
35 }
36 @Override
37 public void windowDeiconified(WindowEvent e) {
38 }
39 @Override
40 public void windowActivated(WindowEvent e) {
41 }
42 @Override
43 public void windowDeactivated(WindowEvent e) {
44 }
45 }
GUI圖形界面中監(jiān)聽器的代碼示例 WEB中的監(jiān)聽器:
事件源:servlet中的三個域對象:ServletContext,HttpSession,ServletRequest.
監(jiān)聽器:自定義類實現8個接口。
事件源和監(jiān)聽器的綁定:配置
WEB中的監(jiān)聽器共有三類八種(監(jiān)聽三個域對象)
一類:監(jiān)聽三個域對象的創(chuàng)建和銷毀;
ServletContextListener
HttpSessionListener
ServletRequestListener
二類:監(jiān)聽三個域對象的屬性變更(屬性添加,移除,替換);
ServletContextAttributeListener
HttpSessioinAttributeListener
ServletRequestAttributeListener
三類:監(jiān)聽HttpSession中JavaBean的狀態(tài)改變(綁定,解除綁定,鈍化,活化);
HttpSessionBindingListener (監(jiān)聽綁定,解除綁定)綁定就是把javabean存入session域中,解除就是把javabean移除或用其他值(非javabean值)替換。
HttpSessionActivationListener (監(jiān)聽鈍化,活化) 鈍化即序列化 活化即反序列化
注意:第三類監(jiān)聽器很特殊,不需要進行配置,作用在JavaBean上的監(jiān)聽器,JavaBean可以自己感知在Session中的狀態(tài);
? ? 讓需要被監(jiān)聽的javabean implements HttpSessionBindingListener/HttpSessionActivationListener,然后重寫里面的方法即可。
? ? 當需要監(jiān)聽某個javabean的鈍化或活化時,該javabean需要實現序列化接口Serializable,否則會報錯。(當正常關閉服務器session域就會發(fā)生鈍化情況,或者通過配置session鈍化時間)
WEB中監(jiān)聽器的使用:
步驟1:編寫一個類實現監(jiān)聽器的接口;
步驟2:通過配置文件配置監(jiān)聽器;
<listener><listener-class>自定義監(jiān)聽器類的全路徑
</listener-class>
</listener> 兩種監(jiān)聽器在企業(yè)中的應用:
ServletContextListener
因為該監(jiān)聽器是監(jiān)聽ServletContext對象的,由于該對象的創(chuàng)建和生命周期的特性可以用來做加載文件或執(zhí)行定時任務。
作用一:加載框架的配置文件;eg:Spring框架 ContextLoaderListener implements ServletContextListener
作用二:執(zhí)行定時任務調度(Timer,TimerTask):(在服務器啟動的時候,定時去執(zhí)行任務)
| Timer API: | ? |
| void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) | 安排指定的任務在指定的時間開始進行重復的固定速率執(zhí)行 |
| void scheduleAtFixedRate(TimerTask task, long delay, long period)? | 安排指定的任務在指定的延遲后開始進行重復的固定速率執(zhí)行。? |
1 package listener;
2
3 import java.util.Calendar;
4 import java.util.Timer;
5 import java.util.TimerTask;
6
7 import javax.naming.NamingException;
8 import javax.servlet.ServletContext;
9 import javax.servlet.ServletContextEvent;
10 import javax.servlet.ServletContextListener;
11
12 import org.apache.naming.SelectorContext;
13
14 public class MyServletContextListener implements ServletContextListener {
15 @Override
16 public void contextInitialized(ServletContextEvent sce) {
17 // 通過事件來獲得事件源
18 ServletContext source = (ServletContext) sce.getSource();
19 System.out.println(source.getServletContextName());
20 // 任務調度示例
21 Timer timer = new Timer();
22 Calendar calendar = Calendar.getInstance();
23 calendar.set(2018, 7, 24, 10, 47, 59);//設置一個時間點
24 //設置服務器啟動后按指定的calendar.getTime()時間執(zhí)行run(),然后接下來每間隔5s執(zhí)行一次.
25 timer.scheduleAtFixedRate(new TimerTask() {
26 @Override
27 public void run() {
28 System.out.println("發(fā)送郵件。。。");
29 }
30 }, calendar.getTime(), 5000);
31 }
32
33 // ServletContext對象銷毀的時候觸發(fā)
34 @Override
35 public void contextDestroyed(ServletContextEvent sce) {
36
37 }
38
39 }
定時任務調度示例一 1 package listener;
2
3 import java.util.Calendar;
4 import java.util.Timer;
5 import java.util.TimerTask;
6
7 import javax.naming.NamingException;
8 import javax.servlet.ServletContext;
9 import javax.servlet.ServletContextEvent;
10 import javax.servlet.ServletContextListener;
11
12 import org.apache.naming.SelectorContext;
13
14 public class MyServletContextListener
implements ServletContextListener {
15 @Override
16 public void contextInitialized(ServletContextEvent sce) {
17 // 通過事件來獲得事件源
18 ServletContext source =
(ServletContext) sce.getSource();
19 System.out.println(source.getServletContextName());
20 // 任務調度示例
21 Timer timer =
new Timer();
22 // 設置服務器啟動后延遲10s后執(zhí)行run(),然后接下來每間隔2s執(zhí)行一次
23 timer.scheduleAtFixedRate(
new TimerTask() {
24 @Override
25 public void run() {
26 System.out.println("發(fā)送郵件。。。"
);
27 }
28 }, 10000, 2000
);
29 }
30
31 // ServletContext對象銷毀的時候觸發(fā)
32 @Override
33 public void contextDestroyed(ServletContextEvent sce) {
34
35 }
36
37 }
定時任務調度示例二 HttpSessionActivationListener
作用:優(yōu)化session
當并發(fā)訪問過大的時候,因為過多的session對象對服務器內存造成巨大的浪費導致性能的下降,我們可以使用該監(jiān)聽器讓規(guī)定一定時長后不使用的session序列化到硬盤,然后再等用的時候反序列化回來,這樣大大節(jié)省了內存,提高了性能。但是我們又不能依賴于服務器的關閉和啟動來實現序列化session,那么我們可以通過配置一個<Context>標簽定時序列化session。
<Context>配置的三種路徑:(放到不同的路徑中對session的作用范圍不同)
一:在tomcat/conf/context.xml中配置一個<Context>; //在tomcat中所有虛擬主機和虛擬路徑都會按照這個配置執(zhí)行。
二:在tomcat/conf/Catalina/localhost/context.xml配置<Context>; //在tomcat中的localhost虛擬主機中的所有虛擬路徑按照這個配置執(zhí)行。
三:在當前工程下的META-INF/context.xml配置<Context>; //當前這個工程按照配置執(zhí)行。
<Context>的配置文檔:
1 <Context>
2 <!--
3 maxIdleSwap:1 表示session1分鐘不用的話就會被自動序列化到硬盤
4 directory:hello 表示序列化后文件存儲的文件夾名稱為hello(work\Catalina\localhost/ProjectName/hello)
5 -->
6 <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
7 <Store className="org.apache.catalina.session.FileStore" directory="hello"/>
8 </Manager>
9 </Context> ?<Context>的配置: ?
轉載于:https://www.cnblogs.com/laodang/p/9530220.html
總結
以上是生活随笔為你收集整理的listener:监听器(加载框架配置文件/执行任务调度/session的优化)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。