java監聽器(Listener)學習筆記


現在來說說Servlet的監聽器Listener,它是實現了javax.servlet.ServletContextListener 接口的服務器端程序,它也是隨web應用的啟動
而啟動,只初始化一次,隨web應用的停止而銷毀。主要作用是:做一些初始化的內容添加工作、設置一些基本的內容、比如一些參數或者是一些

固定的對象等等。首先來看一下ServletContextListener接口的源代碼:

public abstract interface ServletContextListener extends EventListener{  
    public abstract void contextInitialized(ServletContextEvent paramServletContextEvent);  
    public abstract void contextDestroyed(ServletContextEvent paramServletContextEvent);  
} 

根據ServletContextListener監聽器對數據庫連接池DataSource的初始化演示它的使用:ListenerWW.java 

package listener;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;


/** 
 * 現在來說說Servlet的監聽器Listener,它是實現了javax.servlet.ServletContextListener 接口的 
 * 服務器端程序,它也是隨web應用的啟動而啟動,只初始化一次,隨web應用的停止而銷毀。主要作用是:做一些初始化 
 * 的內容添加工作、設置一些基本的內容、比如一些參數或者是一些固定的對象等等。 
 * 示例代碼:使用監聽器對數據庫連接池DataSource進行初始化 
 */
public class ListenerWW implements ServletContextListener {

    //銷毀方法
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        // 在整個web應用銷毀之前調用,將所有應用空間所設置的內容清空  
        servletContext.removeAttribute("dataSource");  
        System.out.println("銷毀工作完成...");    
    }

    //初始化方法
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        // 通過這個事件可以獲取整個應用的空間         
        ServletContext servletContext = servletContextEvent.getServletContext();
        // 在整個web應用下面啟動的時候做一些初始化的內容添加工作 
        // 未導入對應jar包
        BasicDataSource basicDataSource = new BasicDataSource();   
        basicDataSource.setDriverClassName("com.jdbc.Driver");   
        basicDataSource.setUrl("jdbc:mysqlocalhost:3306/");   
        basicDataSource.setUsername("root");     
        basicDataSource.setPassword("root");     
        basicDataSource.setMaxActive(10);//最大連接數     
        basicDataSource.setMaxIdle(5);//最大管理數    
        
        // 把 DataSource 放入ServletContext空間中,     
        // 供整個web應用的使用(獲取數據庫連接)  
        servletContext.setAttribute("dataSource", basicDataSource);     
        System.out.println("應用監聽器初始化工作完成...");     
        System.out.println("已經創建DataSource...");
        
    }

}

配置監聽器的web.xml

 <!-- 配置監聽器 -->
  <listener>
          <listener-class>listener.ListenerWW</listener-class>
  </listener>

監聽器在實際項目中的應用,監聽器在java web中應用的較多,比如:統計當前在線人數、自定義session掃描器。
--------------------- 應用一:統計當前在線人數 ---------------------

代碼實現:

package listener;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;



/** 
 * 說說Session的監聽器Listener,它是實現了javax.servlet.HttpSessionListener 接口的 
 * 例子:在線人數統計
 * @author 旺旺
 */
public class ListenerWW implements HttpSessionListener {

    //在線總人數
    private static int onLinePersonCount = 0;
    
    //session創建
    public void sessionCreated(HttpSessionEvent sessionEvent) {
        //獲取Servlet上下文
        ServletContext servletContext = sessionEvent.getSession().getServletContext();
        onLinePersonCount = (Integer) servletContext.getAttribute("onLinePersonCount");
        // 如果用戶登錄,TOTAL_ONLINE_USERS自增1  
        onLinePersonCount++;  
           servletContext.setAttribute("TOTAL_ONLINE_USERS", onLinePersonCount);  
        
    }

    //session銷毀
    public void sessionDestroyed(HttpSessionEvent sessionEvent) {
        //獲取Servlet上下文
        ServletContext servletContext = sessionEvent.getSession().getServletContext();
        onLinePersonCount = (Integer) servletContext.getAttribute("onLinePersonCount");
        // 如果用戶登錄,TOTAL_ONLINE_USERS自增1  
        onLinePersonCount--;  
        servletContext.setAttribute("TOTAL_ONLINE_USERS", onLinePersonCount);  
    }

    

}

再來一個例子,掃描Session,清理長時間沒有操作的用戶

監聽實例:

package listener;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;



/** 
 * 當網站用戶量增加時,session占用的內存會越來越大,這時session的管理,將會是一項很大的 
 * 系統開銷,為了高效的管理session,我們可以寫一個監聽器,定期清理掉過期的session 
 * @author 旺旺
 */
public class ListenerWW implements HttpSessionListener,ServletContextListener {

    // 創建一個線程安全的集合,用來存儲session  
    List<HttpSession> sessionList = Collections.synchronizedList(new LinkedList<HttpSession>());
    private Object lock = new Object();
    
    //session創建
    public void sessionCreated(HttpSessionEvent sessionEvent) {
        HttpSession httpSession = sessionEvent.getSession();  
        synchronized (lock){  
            sessionList.add(httpSession);  
        }
        
    }

    //session銷毀
    public void sessionDestroyed(HttpSessionEvent sessionEvent) {
        HttpSession httpSession = sessionEvent.getSession();  
        synchronized (lock){  
            sessionList.remove(httpSession);
        } 
    }

    // web應用關閉時觸發contextDestroyed事件  
    public void contextDestroyed(ServletContextEvent servletContextEvent) {  
        System.out.println("web應用關閉...");  
    }  
  
    // web應用啟動時觸發contextInitialized事件  
    public void contextInitialized(ServletContextEvent servletContextEvent) {  
        System.out.println("web應用初始化...");  
        // 創建定時器  
        Timer timer = new Timer();  
        // 每隔30秒就定時執行任務  
        timer.schedule(new WTask(sessionList,lock), 0, 1000*30);  
    }

    

}

定時任務處理類

package listener;

import java.util.List;
import java.util.ListIterator;
import java.util.TimerTask;

import javax.servlet.http.HttpSession;

public class WTask extends TimerTask{

     private List<HttpSession> list;  
     // 存儲傳遞過來的鎖  
     private Object lock;  
     // 構造方法  
     WTask(List<HttpSession> list, Object lock){  
          this.list = list;  
          this.lock = lock;  
     } 
    

    @Override
    public void run() {
        // 考慮到多線程的情況,這里必須要同步
        synchronized (lock) {
            ListIterator<HttpSession> sessionIterator = list.listIterator();
            while(sessionIterator.hasNext()) {
                //五分鍾沒有訪問后台
                // httpSession.getLastAccessedTime() = session的最后訪問時間
                HttpSession httpSession = sessionIterator.next();
                if((System.currentTimeMillis() - httpSession.getLastAccessedTime()) > 1000*60*5) {
                    // 手動銷毀session  
                    httpSession.invalidate();  
                    // 從集合中移除已經被銷毀的session  
                    sessionIterator.remove();  
                }
            }
            /*for(HttpSession httpSession : list) {
                //五分鍾沒有訪問后台
                // httpSession.getLastAccessedTime() = session的最后訪問時間
                if((System.currentTimeMillis() - httpSession.getLastAccessedTime()) > 1000*60*5) {
                    // 手動銷毀session  
                    httpSession.invalidate();  
                    // 從集合中移除已經被銷毀的session  
                    list.remove(httpSession);  
                }
            }*/
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM