现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动
而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些

固定的对象等等。首先来看一下ServletContextListener接口的源代码:

  1. public abstract interface ServletContextListener extends EventListener{
  2. public abstract void contextInitialized(ServletContextEvent paramServletContextEvent);
  3. public abstract void contextDestroyed(ServletContextEvent paramServletContextEvent);
  4. }

下面利用监听器对数据库连接池DataSource的初始化演示它的使用:ListenerTest.java

  1. import javax.servlet.ServletContext;
  2. import javax.servlet.ServletContextEvent;
  3. import javax.servlet.ServletContextListener;
  4. import org.apache.commons.dbcp.BasicDataSource;
  5. /**
  6. * 现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的
  7. * 服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化
  8. * 的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
  9. *
  10. * 示例代码:使用监听器对数据库连接池DataSource进行初始化
  11. */
  12. public class ListenerTest implements ServletContextListener{
  13. // 应用监听器的销毁方法
  14. public void contextDestroyed(ServletContextEvent servletContextEvent) {
  15. ServletContext servletContext = servletContextEvent.getServletContext();
  16. // 在整个web应用销毁之前调用,将所有应用空间所设置的内容清空
  17. servletContext.removeAttribute("dataSource");
  18. System.out.println("销毁工作完成...");
  19. }
  20. // 应用监听器的初始化方法
  21. public void contextInitialized(ServletContextEvent servletContextEvent) {
  22. // 通过这个事件可以获取整个应用的空间
  23. // 在整个web应用下面启动的时候做一些初始化的内容添加工作
  24. ServletContext servletContext = servletContextEvent.getServletContext();
  25. // 设置一些基本的内容;比如一些参数或者是一些固定的对象
  26. // 创建DataSource对象,连接池技术 dbcp
  27. BasicDataSource basicDataSource = new BasicDataSource();
  28. basicDataSource.setDriverClassName("com.jdbc.Driver");
  29. basicDataSource.setUrl("jdbc:mysqlocalhost:3306/");
  30. basicDataSource.setUsername("root");
  31. basicDataSource.setPassword("root");
  32. basicDataSource.setMaxActive(10);//最大连接数
  33. basicDataSource.setMaxIdle(5);//最大管理数
  34. //bds.setMaxWait(maxWait); 最大等待时间
  35. // 把 DataSource 放入ServletContext空间中,
  36. // 供整个web应用的使用(获取数据库连接)
  37. servletContext.setAttribute("dataSource", basicDataSource);
  38. System.out.println("应用监听器初始化工作完成...");
  39. System.out.println("已经创建DataSource...");
  40. }
  41. }

web.xml中配置如下,很简单:

  1. <!-- 配置应用监听器  -->
  2. <listener>
  3. <listener-class>com.ycq.ListenerTest</listener-class>
  4. </listener>

这样配置好了之后,以后在web应用中就可以通过ServletContext取得BasicDataSource对象,从而获取与数据库的连接,提高性能,方便使用。

示例代码二:

  1. import java.io.File;
  2. import javax.servlet.ServletContextEvent;
  3. import javax.servlet.ServletContextListener;
  4. import com.i2f.fsp.deploy.TransactionDeployer;
  5. /**
  6. * 监听器随着项目的启动而启动
  7. *
  8. */
  9. public class ListenerTest2 implements ServletContextListener{
  10. // 销毁监听器
  11. public void contextDestroyed(ServletContextEvent servletContextEvent) {
  12. System.out.println("date20161020095500 :" + servletContextEvent.getServletContext());
  13. }
  14. public void contextInitialized(ServletContextEvent servletContextEvent) {
  15. try{
  16. // 获取项目跟路径
  17. String basePath = servletContextEvent.getServletContext().getRealPath("/");
  18. // D:\apache-tomcat-6.0.41\webapps\i2money\ 绝对路径
  19. System.out.println("basePath20161020094700 :" + basePath);
  20. if (!(basePath.endsWith(File.separator))){
  21. basePath = basePath + File.separator;
  22. }
  23. basePath = basePath + "WEB-INF" + File.separator + "classes" + File.separator;
  24. new TransactionDeployer(basePath).deploy();
  25. // D:\apache-tomcat-6.0.41\webapps\i2money\WEB-INF\classes\
  26. System.out.println("basePath20161020094701 :" + basePath);
  27. }
  28. catch (Exception e){
  29. e.printStackTrace();
  30. System.exit(-1);
  31. }
  32. }
  33. }

示例代码三:

  1. import javax.servlet.http.HttpSession;
  2. import javax.servlet.http.HttpSessionEvent;
  3. import javax.servlet.http.HttpSessionListener;
  4. import org.apache.commons.logging.Log;
  5. import org.apache.commons.logging.LogFactory;
  6. import org.springframework.context.ApplicationContext;
  7. import org.springframework.web.context.support.WebApplicationContextUtils;
  8. public class UserLogoutListener implements HttpSessionListener{
  9. protected final Log log = LogFactory.getLog(super.getClass());
  10. public void sessionCreated(HttpSessionEvent event){
  11. this.log.error("session created. id = " + event.getSession().getId());
  12. }
  13. public void sessionDestroyed(HttpSessionEvent event){
  14. this.log.error("session destroyed.id = " + event.getSession().getId());
  15. HttpSession session = event.getSession();
  16. ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
  17. OnlineUserMonitorClient client = (OnlineUserMonitorClient)context.getBean("onlineUserMonitorClient");
  18. client.afterSessionDestroyed(session);
  19. }
  20. }

监听器在实际项目中的应用,监听器在java web中应用的较多,比如:统计当前在线人数、自定义session扫描器。
--------------------- 应用一:统计当前在线人数 ---------------------

  1. import javax.servlet.ServletContext;
  2. import javax.servlet.http.HttpSessionEvent;
  3. import javax.servlet.http.HttpSessionListener;
  4. /**
  5. * @description HttpSessionListener监听器实现统计网站在线人数的功能
  6. */
  7. public class SessionListener implements HttpSessionListener{
  8. public static int TOTAL_ONLINE_USERS = 0;
  9. public void sessionCreated(HttpSessionEvent httpSessionEvent) {
  10. ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
  11. TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");
  12. // 如果用户退出,TOTAL_ONLINE_USERS自减1
  13. if(TOTAL_ONLINE_USERS == 0){
  14. servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);
  15. }
  16. else{
  17. TOTAL_ONLINE_USERS--;
  18. servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);
  19. }
  20. }
  21. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
  22. ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
  23. TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");
  24. // 如果用户登录,TOTAL_ONLINE_USERS自增1
  25. if(TOTAL_ONLINE_USERS == 0){
  26. servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);
  27. }
  28. else{
  29. TOTAL_ONLINE_USERS++;
  30. servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);
  31. }
  32. }
  33. }

--------------------- 应用二:自定义session扫描器 ---------------------

  1. import java.util.LinkedList;
  2. import java.util.List;
  3. import java.util.Timer;
  4. import javax.servlet.ServletContextEvent;
  5. import javax.servlet.ServletContextListener;
  6. import javax.servlet.http.HttpSession;
  7. import javax.servlet.http.HttpSessionEvent;
  8. import javax.servlet.http.HttpSessionListener;
  9. import jeus.util.concurrent50.Collections;
  10. /**
  11. * @description 当网站用户量增加时,session占用的内存会越来越大,这时session的管理,将会是一项很大的
  12. * 系统开销,为了高效的管理session,我们可以写一个监听器,定期清理掉过期的session
  13. */
  14. public class SessionScanerListener implements HttpSessionListener,ServletContextListener{
  15. // 创建一个线程安全的集合,用来存储session
  16. @SuppressWarnings("unchecked")
  17. List<HttpSession> sessionList = Collections.synchronizedList(new LinkedList<HttpSession>());
  18. private Object lock = new Object();
  19. public void sessionCreated(HttpSessionEvent httpSessionEvent) {
  20. System.out.println("session 创建成功...");
  21. HttpSession httpSession = httpSessionEvent.getSession();
  22. synchronized (lock){
  23. sessionList.add(httpSession);
  24. }
  25. }
  26. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
  27. System.out.println("session 销毁成功...");
  28. }
  29. // web应用关闭时触发contextDestroyed事件
  30. public void contextDestroyed(ServletContextEvent servletContextEvent) {
  31. System.out.println("web应用关闭...");
  32. }
  33. // web应用启动时触发contextInitialized事件
  34. public void contextInitialized(ServletContextEvent servletContextEvent) {
  35. System.out.println("web应用初始化...");
  36. // 创建定时器
  37. Timer timer = new Timer();
  38. // 每隔30秒就定时执行任务
  39. timer.schedule(new MyTask(sessionList,lock), 0, 1000*30);
  40. }
  41. }
    1. import java.util.List;
    2. import java.util.ListIterator;
    3. import java.util.TimerTask;
    4. import javax.servlet.http.HttpSession;
    5. /**
    6. * 定时器,定义定时任务的具体内容
    7. */
    8. public class MyTask extends TimerTask{
    9. private List<HttpSession> list;
    10. // 存储传递过来的锁
    11. private Object lock;
    12. // 构造方法
    13. MyTask(List<HttpSession> list, Object lock){
    14. this.list = list;
    15. this.lock = lock;
    16. }
    17. @Override
    18. public void run() {
    19. // 考虑到多线程的情况,这里必须要同步
    20. synchronized (lock){
    21. System.out.println("定时器开始执行...");
    22. ListIterator<HttpSession> listIterator = list.listIterator();
    23. while(listIterator.hasNext()){
    24. HttpSession httpSession = listIterator.next();
    25. // httpSession.getLastAccessedTime() = session的最后访问时间
    26. if(System.currentTimeMillis() - httpSession.getLastAccessedTime() > 1000*30){
    27. // 手动销毁session
    28. httpSession.invalidate();
    29. // 从集合中移除已经被销毁的session
    30. listIterator.remove();
    31. }
    32. }
    33. }
    34. }
    35. }

Java三大器之监听器(Listener)的工作原理和代码演示的更多相关文章

  1. Java三大器之过滤器(Filter)的工作原理和代码演示

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet, 静 ...

  2. Java中的Annotation(2)----Annotation工作原理

    Java中的Annotation(2)----Annotation工作原理 分类: 编程语言2013-03-18 01:06 3280人阅读 评论(6) 收藏 举报 上一篇文章已经介绍了如何使用JDK ...

  3. jdk1.8 ConcurrentHashMap 的工作原理及代码实现,如何统计所有的元素个数

    ConcurrentHashMap 的工作原理及代码实现: 相比于1.7版本,它做了两个改进 1.取消了segment分段设计,直接使用Node数组来保存数据,并且采用Node数组元素作为锁来实现每一 ...

  4. java之Servlet监听器Listener

    常用应用场景:单点登录.统计在线人数 一.简介 (一)概述 1.Listener 用于监听 java web程序中的事件,例如创建.修改.删除Session.request.context等,并触发响 ...

  5. JAVA NIO工作原理及代码示例

    简介:本文主要介绍了JAVA NIO中的Buffer, Channel, Selector的工作原理以及使用它们的若干注意事项,最后是利用它们实现服务器和客户端通信的代码实例. 欢迎探讨,如有错误敬请 ...

  6. Java web每天学之Servlet工作原理详情解析

    上篇文章中我们介绍了Servlet的实现方式以及Servlet的生命周期,我们这篇文章就来介绍一下常用对象. 点击回顾:<Java Web每天学之Servlet的工作原理解析>:<J ...

  7. 【java web】监听器listener

    一.简介 Java的监听器,也是系统级别的监听.监听器随web应用的启动而启动.Java的监听器在c/s模式里面经常用到,它会对特定的事件产生产生一个处理.监听在很多模式下用到,比如说观察者模式,就是 ...

  8. ConcurrentHashMap 的工作原理及代码实现

    ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组.Segment继承了ReentrantLock,所 ...

  9. HashMap 的工作原理及代码实现,什么时候用到红黑树

    HashMap工作原理及什么时候用到的红黑树: 在jdk 1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里.但是当位于一个桶中的元素较多,即has ...

随机推荐

  1. 《机器学习实战》读书笔记—k近邻算法c语言实现(win下)

    #include <stdio.h> #include <io.h> #include <math.h> #include <stdlib.h> #de ...

  2. 非常好的Linux教程,让你的linux之路更通畅

    1  第1讲.Linux应用与发展(上) 2013-10-22 17:43 | 播放(46) | 评论(0) | 时长:51:38 2  第1讲.Linux应用与发展(下) 2013-10-22 17 ...

  3. 浅谈android Socket 通信及自建ServerSocket服务端常见问题

    摘  要:TCP/IP通信协议是可靠的面向连接的网络协议,它在通信两端各建立一个Socket,从而在两端形成网络虚拟链路,进而应用程序可通过可以通过虚拟链路进行通信.Java对于基于TCP协议的网络通 ...

  4. 让Vs2010支持 Css3+HTML5

    第一步. 先到微软官方下载一个 Microsoft Visual Studio 2010 sp1 . 给传送门:.microsoft.com/downloads/zh-cn/details.aspx? ...

  5. SoundPool 播放提示音

    SoundPool 一个声音播放的辅助类,从名字可以看出,它具有 “池”的能力,它先加载声音文件到内存,以支持多次播放声音文件. 特点 SoundPool适合 短小的 声音文件 SoundPool适合 ...

  6. SQL Server 中使用 Try Catch 处理异常

    CREATE TABLE ErrorLog( errNum INT, ErrSev ), ErrState INT, ErrProc ), ErrLine INT, ErrMsg ) ) CREATE ...

  7. NEMA协议详解

    NEMA协议的由来 NMEA协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,由美国国家海洋电子协会(NMEA-The   National Marin ...

  8. 给notepad++加nppFtp插件连接ubuntu编写文本

    打开notepad++的菜单栏中的插件,如果没有“插件管理”,去https://github.com/ashkulz/NppFTP/releases/tag/v0.27.2,下载对应的版本,将其解压后 ...

  9. msvc/gcc:中用#pragma指令关闭特定警告(warning)

    在使用一些第三方库或源码的时候,经常会遇到编译时产生warnings情况,这些warning不是我们自己的代码产生的,当然也不好去修改,但每次编译都显示一大堆与自己代码无关的警告也着实看着不爽,更麻烦 ...

  10. windows 2012(64位) IIS配置asp程序 500 - 内部服务器错误。您查找的资源存在问题,因而无法显示。

    在网上找了很久,包括常规的设置父路径之类的,一直都不可以,搞了一晚上毫无成就感,第二天早上无意中看到一篇文章,说到点子上了,非常感谢.源地址已经找不到了,我把大概的问题截图说明一下. 方法如下:1.打 ...