Listener的定义与作用

监听器Listener就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。

Listener是Servlet的监听器,可以监听客户端的请求,服务端的操作等。

Listener的分类与使用

主要有以下三类:

ServletContext监听

ServletContextListener:用于对Servlet整个上下文进行监听(创建、销毁)。

//上下文初始化
public void contextInitialized(ServletContextEvent sce);
//上下文销毁
public void contextDestroyed(ServletContextEvent sce);
//ServletContextEvent事件:取得一个ServletContext(application)对象
public ServletContext getServletContext();

ServletContextAttributeListener:对Servlet上下文属性的监听(增删改属性)。

//增加属性
public void attributeAdded(ServletContextAttributeEvent scab);
//属性删除
public void attributeRemoved(ServletContextAttributeEvent scab);
//属性替换(第二次设置同一属性)
public void attributeRepalced(ServletContextAttributeEvent scab); //ServletContextAttributeEvent事件:能取得设置属性的名称与内容
//得到属性名称
public String getName();
//取得属性的值
public Object getValue();

Session监听

Session属于http协议下的内容,接口位于javax.servlet.http.*包下。

HttpSessionListener接口:对Session的整体状态的监听。

//session创建
public void sessionCreated(HttpSessionEvent se);
//session销毁
public void sessionDestroyed(HttpSessionEvent se); //HttpSessionEvent事件:
//取得当前操作的session
public HttpSession getSession();

HttpSessionAttributeListener接口:对session的属性监听。

public void attributeAdded(HttpSessionBindingEvent se);//增加属性
public void attributeRemoved(HttpSessionBindingEvent se);//删除属性
public void attributeReplaced(HttpSessionBindingEvent se);//替换属性 //HttpSessionBindingEvent事件:
public String getName();//取得属性的名称
public Object getValue();//取得属性的值
public HttpSession getSession();//取得当前的session

session的销毁有两种情况:

1.session超时,web.xml配置:

<session-config>
<session-timeout>120</session-timeout><!--session120分钟后超时销毁-->
</session-config>

2.手工使session失效

//使session失效方法。session.invalidate();
public void invalidate();

Request监听

ServletRequestListener:用于对Request请求进行监听(创建、销毁)。

public void requestInitialized(ServletRequestEvent sre);//request初始化
public void requestDestroyed(ServletRequestEvent sre);//request销毁 //ServletRequestEvent事件:
public ServletRequest getServletRequest();//取得一个ServletRequest对象
public ServletContext getServletContext();//取得一个ServletContext(application)对象

ServletRequestAttributeListener:对Request属性的监听(增删改属性)。

public void attributeAdded(ServletRequestAttributeEvent srae);//增加属性
public void attributeRemoved(ServletRequestAttributeEvent srae);//属性删除
public void attributeReplaced(ServletRequestAttributeEvent srae);//属性替换(第二次设置同一属性) //ServletRequestAttributeEvent事件:能取得设置属性的名称与内容
public String getName();//得到属性名称
public Object getValue();//取得属性的值

在web.xml中配置

Listener配置信息必须在Filter和Servlet配置之前,Listener的初始化(ServletContentListener初始化)比Servlet和Filter都优先,而销毁比Servlet和Filter都慢。

<listener>
<listener-class>com.listener.class</listener-class>
</listener>

Listener应用实例

利用HttpSessionListener统计最多在线用户人数

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; public class HttpSessionListenerImpl implements HttpSessionListener { public void sessionCreated(HttpSessionEvent event) {
ServletContext app = event.getSession().getServletContext();
int count = Integer.parseInt(app.getAttribute("onLineCount").toString());
count++;
app.setAttribute("onLineCount", count);
int maxOnLineCount = Integer.parseInt(app.getAttribute("maxOnLineCount").toString());
if (count > maxOnLineCount) {
//记录最多人数是多少
app.setAttribute("maxOnLineCount", count);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//记录在那个时刻达到上限
app.setAttribute("date", df.format(new Date()));
}
}
//session注销、超时时候调用,停止tomcat不会调用
public void sessionDestroyed(HttpSessionEvent event) {
ServletContext app = event.getSession().getServletContext();
int count = Integer.parseInt(app.getAttribute("onLineCount").toString());
count--;
app.setAttribute("onLineCount", count); }
}

Spring使用ContextLoaderListener加载ApplicationContext配置信息

ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

ContextLoaderListener如何查找ApplicationContext.xml的配置位置以及配置多个xml:如果在web.xml中不写任何参数配置信息,默认的路径是”/WEB-INF/applicationContext.xml”,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml(在MyEclipse中把xml文件放置在src目录下)。如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数。

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value><!-- 采用的是通配符方式,查找WEB-INF/spring目录下xml文件。如有多个xml文件,以“,”分隔。 -->
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Spring使用Log4jConfigListener的好处:Spring使用Log4jConfigListener配置Log4j日志

  • 动态的改变记录级别和策略,不需要重启Web应用。
  • 把log文件定在 /WEB-INF/logs/ 而不需要写绝对路径。因为系统把web目录的路径压入一个叫webapp.root的系统变量。这样写log文件路径时不用写绝对路径了。
  • 可以把log4j.properties和其他properties一起放在/WEB-INF/ ,而不是Class-Path。
  • 设置log4jRefreshInterval时间,开一条watchdog线程每隔段时间扫描一下配置文件的变化。
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>project.root</param-value><!-- 用于定位log文件输出位置在web应用根目录下,log4j配置文件中写输出位置:log4j.appender.FILE.File=${project.root}/logs/project.log -->
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value><!-- 载入log4j配置文件 -->
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value><!--Spring刷新Log4j配置文件的间隔60秒,单位为millisecond-->
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

Spring使用IntrospectorCleanupListener清理缓存

这个监听器的作用是在web应用关闭时刷新JDK的JavaBeans的Introspector缓存,以确保Web应用程序的类加载器以及其加载的类正确的释放资源。

如果JavaBeans的Introspector已被用来分析应用程序类,系统级的Introspector缓存将持有这些类的一个硬引用。因此,这些类和Web应用程序的类加载器在Web应用程序关闭时将不会被垃圾收集器回收!而IntrospectorCleanupListener则会对其进行适当的清理,已使其能够被垃圾收集器回收。

唯一能够清理Introspector的方法是刷新整个Introspector缓存,没有其他办法来确切指定应用程序所引用的类。这将删除所有其他应用程序在服务器的缓存的Introspector结果。

在使用Spring内部的bean机制时,不需要使用此监听器,因为Spring自己的introspection results cache将会立即刷新被分析过的JavaBeans Introspector cache,而仅仅会在应用程序自己的ClassLoader里面持有一个cache。虽然Spring本身不产生泄漏,注意,即使在Spring框架的类本身驻留在一个“共同”类加载器(如系统的ClassLoader)的情况下,也仍然应该使用使用IntrospectorCleanupListener。在这种情况下,这个IntrospectorCleanupListener将会妥善清理Spring的introspection cache。

应用程序类,几乎不需要直接使用JavaBeans Introspector,所以,通常都不是Introspector resource造成内存泄露。相反,许多库和框架,不清理Introspector,例如: Struts和Quartz。

需要注意的是一个简单Introspector泄漏将会导致整个Web应用程序的类加载器不会被回收!这样做的结果,将会是在web应用程序关闭时,该应用程序所有的静态类资源(比如:单实例对象)都没有得到释放。而导致内存泄露的根本原因其实并不是这些未被回收的类!

注意:IntrospectorCleanupListener应该注册为web.xml中的第一个Listener,在任何其他Listener之前注册,比如在Spring’s ContextLoaderListener注册之前,才能确保IntrospectorCleanupListener在Web应用的生命周期适当时机生效。

<listener><!-- memory clean -->
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

Java中的Listener 监听器的更多相关文章

  1. [Java] JSP笔记 - Listener 监听器

    Java Web 开发时,可以使用 Listener 来监听来监听一些事件,从而实现一些功能.实际上这个监听器,原理就是 Delphi 中大家常用的各种事件. 1. 那么,监听器的主要用途用哪些呢: ...

  2. java中过滤器、监听器、拦截器的区别

    1.过滤器:所谓过滤器顾名思义是用来过滤的,在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的actio ...

  3. java中servletContextListener、httpSessionListener和servletRequestListener使用整理

    在java web应用中,listener监听器似乎是必不可少的,常常用来监听servletContext.httpSession.servletRequest等域对象的创建.销毁以及属性的变化等等, ...

  4. Java ---Listener监听器

    在我们的web容器中,一直不断的触发着各种事件,例如:web应用启动和关闭,request请求到达和结束等.但是这些事件通常对于开发者来说是透明的,我们可以根据这些接口开发符合我们自身需求的功能.在w ...

  5. 【Servlet】Java Serlvet Listener 监听器

    Listener监听器 Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理 容器产生的事件分类 - 生命周期相关的事件 - 设置和删除Attribute数据 ...

  6. java中jna使用回调实现事件监听器——观察者模式

    (1)C接口中的接口头文件 #pragma once #include <iostream> #include <vector> #include <core/core. ...

  7. 【转】转帖并注释:Java中的事件处理机制--事件监听器的四种实现方式

    原文地址:http://blog.sina.com.cn/s/blog_4b650d650100nqws.html Java中四种事件监听器的实现方式分别为: 自身类做为事件监听器 外部类作为事件监听 ...

  8. 16)JAVA实现回调(Android,Swing中各类listener的实现)

           熟悉MS-Windows和X Windows事件驱动设计模式的开发人员,通常是把一个方法的指针传递给事件源,当某一事件发生时来调用这个方法(也称为"回调").Java ...

  9. java中实现定时功能

    网上资料: 我们可以使用Timer和TimerTask类在java中实现定时任务,详细说明如下: 1.基础知识java.util.Timer一种线程设施,用于安排以后在后台线程中执行的任务.可安排任务 ...

随机推荐

  1. @ResponseBody使用

    @responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML 数据,需 ...

  2. OpenCV Python 4.0安装

    1.安装OpenCV-Python 如果你是第一次使用OpenCV Python开发包,想要安装OpenCV Python4.0只要执行如下命令行即可: pip install opencv-pyth ...

  3. mysql 开启log-bin功能

      今天搜索了一下增量备份脚本,简单查了一下,增量备份是通过mysql binlog来做的,就是将某段时间内的操作,保存到某二进制日志当中.备份就是备这个日志,恢复也是通过它.然鹅,这里我们需要先开启 ...

  4. 通过 Spring Session 实现新一代的 Session 管理

    长期以来,session 管理就是企业级 Java 中的一部分,以致于我们潜意识就认为它是已经解决的问题,在最近的记忆中,我们没有看到这个领域有很大的革新. 但是,现代的趋势是微服务以及可水平扩展的原 ...

  5. Java基础---Java三元运算

    一元运算符:只需要一个数据就可以进行操作的运算符.例如:取反!.自增++.自减--二元运算符:需要两个数据才可以进行操作的运算符.例如:加法+.赋值=三元运算符:需要三个数据才可以进行操作的运算符. ...

  6. PPT 中用 LaTeX 插入公式、PowerPoint 中用 LaTeX 插入公式(4)

    步骤: 1. 安装 CTex 2. 安装 IguanaTex >> 下载链接1:官网 >> 下载链接2:复制链接到迅雷或IDM下载很快 3. 将「IguanaTex_v1_56 ...

  7. 封装ADO库之MFC应用

    Microsoft Activex Data Objects(ADO)支持用于建立基于客户端/服务器和web的应用程序开发的主要功能.其主要优点是易于使用.高速度.低内存支出和占用磁盘空间较少. 本次 ...

  8. 剑指offer36:两个链表的第一个公共结点

    1 题目描述 输入两个链表,找出它们的第一个公共结点. 2 思路和方法 方法一: 用两个指针同时从两个链表的表头开始走,当走到自己的链表结尾的时候开始从另一个链表的表头开始向后走.终止条件就是两个指针 ...

  9. php实现微信小程序登录

    以上是官方的流程介绍,已经说的很详细了,现在简单介绍一下流程 前端通过wx.login生成code传递给后端,后端通过提交Appid + appSecret + code 到微信方服务器 获取 ses ...

  10. python之RabbitMQ队列

    一.介绍 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议. MQ全称为Message Queue, 消息队列(MQ)是一 ...