Listener 监听器

来源:互联网 发布:淘宝pc转无线连接 编辑:程序博客网 时间:2024/04/25 15:11
前言:之前写了一篇关于Filter的文章:http://tianweili.github.io/blog/2015/01/26/java-filter/,现在再来一篇Listener的,Filter和Listener在项目中是经常用到的,巧妙的使用可以达到事半功倍的效果。故把两者的用法总结一下。


  原文链接:http://tianweili.github.io/blog/2015/01/27/java-listener/


1、Listener的定义与作用


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


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


2、Listener的分类与使用


  主要有以下三类:


  1、ServletContext监听


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


public void contextInitialized(ServletContextEvent sce);//上下文初始化
public void contextDestroyed(ServletContextEvent sce);//上下文销毁


public ServletContext getServletContext();//ServletContextEvent事件:取得一个ServletContext(application)对象
  ServletContextAttributeListener:对Servlet上下文属性的监听(增删改属性)。


public void attributeAdded(ServletContextAttributeEvent scab);//增加属性
public void attributeRemoved(ServletContextAttributeEvent scab);//属性删除
public void attributeRepalced(ServletContextAttributeEvent scab);//属性替换(第二次设置同一属性)


//ServletContextAttributeEvent事件:能取得设置属性的名称与内容
public String getName();//得到属性名称
public Object getValue();//取得属性的值
  2、Session监听


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


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


public void sessionCreated(HttpSessionEvent se);//session创建
public void sessionDestroyed(HttpSessionEvent se);//session销毁


//HttpSessionEvent事件:
public HttpSession getSession();//取得当前操作的session
  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失效


public void invalidate();//使session失效方法。session.invalidate();
  3、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();//取得属性的值
  4、在web.xml中配置


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


<listener>
    <listener-class>com.listener.class</listener-class>
</listener>
3、Listener应用实例


  1、利用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);    
        
    }
}
  2、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>
  3、Spring使用Log4jConfigListener配置Log4j日志


  Spring使用Log4jConfigListener的好处:


动态的改变记录级别和策略,不需要重启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>
  4、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应用的生命周期适当时机生效。


<!-- memory clean -->
<listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
 原文链接:http://tianweili.github.io/blog/2015/01/27/java-listener/
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 出车祸了报警警察不管怎么办 高中的孩子不好好上学怎么办 和老公消费观念不合拍怎么办 去医院没带现金怎么办 微信读书下架了怎么办 24岁血压有点高怎么办 吃鸡鼠标弹出来怎么办 电脑分辨率调错了怎么办 猎豹sc9打不开门怎么办 苹果手机卡顿反应慢怎么办 金立手机卡顿反应慢怎么办 20天宝宝黄疸219怎么办? 智慧树选修挂科怎么办 军人被纠察抓了怎么办 我家的小孩很凶怎么办 10岁儿童老挤眼怎么办? 脚趾长鸡眼好痛怎么办 月加班超过36小时怎么办 月经老提前怎么办才好 20岁例假不规律怎么办 农村的医保门诊封顶了怎么办 保研夏令营被拒怎么办 小学生去英国游学怎么办签证 医生说我湿气重怎么办 喉咙痛有来医生感冒喉咙痛怎么办 暴马丁香叶子卷怎么办 房产权40年以后怎么办 面试回答不了考官的问题怎么办 轻伤事故对方要钱太多我怎么办 退休后有房子住公积金怎么办 江苏副高评过不聘怎么办 抗环瓜氨酸肽抗体高怎么办 脚被磨破了好痛怎么办 脚磨破皮肿了怎么办 脚磨破皮发炎了怎么办 3个月婴儿流口水怎么办 beats耳机被偷了怎么办 beats X耳机丢了怎么办 头戴耳机戴着热怎么办 长时间戴耳机耳朵疼怎么办 手表秒针走得声音很大怎么办