现在来说说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);
}
}*/
}
} }

java监听器(Listener)学习笔记的更多相关文章

  1. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  2. Java多线程技术学习笔记(二)

    目录: 线程间的通信示例 等待唤醒机制 等待唤醒机制的优化 线程间通信经典问题:多生产者多消费者问题 多生产多消费问题的解决 JDK1.5之后的新加锁方式 多生产多消费问题的新解决办法 sleep和w ...

  3. Java安全防御学习笔记V1.0

    Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  6. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  7. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  8. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  9. java之jvm学习笔记十三(jvm基本结构)

    java之jvm学习笔记十三(jvm基本结构) 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成 ...

  10. Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)

    Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...

随机推荐

  1. 如何使用 Packer 在 Azure 中创建 Windows 虚拟机映像

    Azure 中的每个虚拟机 (VM) 都是基于定义 Windows 分发和操作系统版本的映像创建的. 映像可以包括预安装的应用程序和配置. Azure 应用商店为最常见的操作系统和应用程序环境提供了许 ...

  2. Tmux 使用教程 on Fedora 28

    Tmux 和 gun/screen 都是优秀的终端复用软件,它的关键的好处就是,保持ssh 登录连接session不中断,并且能支持分屏操作,具备丰富的命令行参数,可以进行动态布局和操作.可以看作为s ...

  3. python的学习之路day6

    大纲: 1.反射 其中的方法:getattr,delattr,setattr,hasattr __import__() __import__() 注意事项 2.模块中的特殊变量 __doc__ __c ...

  4. 【爬坑】MySQL 无法启动

    [说明] 启动 MySQL 的时候出现以下错误 [解决] 在网上查到了遇到相关问题的人的解决方法,参考连接 Mysql启动报错 原因是 MySQL 服务没启动,开启就好了. 最后分析之所以服务没开启, ...

  5. 安全之路 —— C/C++实现后门的服务自启动

    简介 Windows NT系统后门要实现自启动,有许多种方法,例如注册表自启动,映像劫持技术,SVCHost自启动以及本章节介绍的服务自启动等方法,其中服务自启动相对于上述其他三种需要修改注册表的启动 ...

  6. MySQL报错:error1130

    ERROR (HY000): Host 'ip-172-31-x-x.ec2.internal' is not allowed to connect to this MySQL server 分析,从 ...

  7. 拉格朗日插值和牛顿插值 matlab

    1. 已知函数在下列各点的值为   0.2 0.4 0.6 0.8 1.0   0.98 0.92 0.81 0.64 0.38 用插值法对数据进行拟合,要求给出Lagrange插值多项式和Newto ...

  8. Jenkins 角色 项目权限管理

    插件名称: Role-based Authorization Strategy 新建 两用户 配置项目安全策略  在系统管理页面点击Manage and Assign Roles进入角色管理页面: 进 ...

  9. 1)HDFS分布式文件系统 2)HDFS核心设计 3 )HDFS体系结构

    一.HDFS简介 1.HDFS:Hadoop distributed file system 一个分布式文件系统 基于流数据模式访问和处理超大文件的需要而开发 适合应用在大规模数据集上 2. 优点 处 ...

  10. python第二十六课——装饰器

    装饰器是闭包的一种使用场景: python中的装饰器在定义上需要传入一个函数对象, 在此函数执行之前或者之后都可以追加其它的操作, 这样做的好处是,在不改变源码(原本业务逻辑的)同时,进行功能的扩展: ...