• 【转】监听器(Listener)学习


    一、监听器介绍

    1.1、监听器的概念

      监听器是一个专门用于对其它对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监听的对象发生情况时,立即采取相应的行动。监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听的对象发生上述事件就,监听器的某个方法立即被执行

    1.2、设计一个可以被别的对象监听的对象

      我们平时做开发的时候,我们是写监听器去监听其他对象,那么我们如果想设计一个对象,让这个对象可以被别的对象监听又该怎么做呢,可以按照严格的事件处理模型来设计一个对象,这个对象就可以被别的对象监听,事件处理模型涉及到三个组件:事件源、事件对象、事件监听器。

      下面我们来按照事件处理模型来设计一个Person对象,具体代码如下:

      1 package me.gacl.observer;
      2 
      3 /**
      4 * @ClassName: Person(事件源)
      5 * @Description: 设计一个Person类作为事件源,这个类的对象的行为(比如吃饭、跑步)可以被其他的对象监听
      6 * @author: 孤傲苍狼
      7 * @date: 2014-9-9 下午9:26:06
      8 *
      9 */  
     10 public class Person {
     11     /**
     12     * @Field: listener
     13     *          在Person类中定义一个PersonListener变量来记住传递进来的监听器
     14     */ 
     15     private PersonListener listener;
     16 
     17     /**
     18     * @Method: eat
     19     * @Description: 设计Person的行为:吃
     20     * @Anthor:孤傲苍狼
     21     *
     22     */ 
     23     public void eat() {
     24         if (listener != null) {
     25             /**
     26              * 调用监听器的doeat方法监听Person类对象eat(吃)这个动作,将事件对象Event传递给doeat方法,
     27              * 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
     28              */
     29             listener.doeat(new Event(this));
     30         }
     31     }
     32 
     33     /**
     34     * @Method: run
     35     * @Description: 设计Person的行为:跑
     36     * @Anthor:孤傲苍狼
     37     *
     38     */ 
     39     public void run() {
     40         if (listener != null) {
     41             /**
     42              * 调用监听器的dorun方法监听Person类对象run(跑)这个动作,将事件对象Event传递给doeat方法,
     43              * 事件对象封装了事件源,new Event(this)中的this代表的就是事件源
     44              */
     45             listener.dorun(new Event(this));
     46         }
     47     }
     48 
     49     /**
     50     * @Method: registerListener
     51     * @Description: 这个方法是用来注册对Person类对象的行为进行监听的监听器
     52     * @Anthor:孤傲苍狼
     53     *
     54     * @param listener
     55     */ 
     56     public void registerListener(PersonListener listener) {
     57         this.listener = listener;
     58     }
     59 }
     60 
     61 /**
     62 * @ClassName: PersonListener(事件监听器)
     63 * @Description: 设计Person类(事件源)的监听器接口
     64 * @author: 孤傲苍狼
     65 * @date: 2014-9-9 下午9:28:06
     66 *
     67 */ 
     68 interface PersonListener {
     69 
     70     /**
     71     * @Method: doeat
     72     * @Description: 这个方法是用来监听Person对象eat(吃)这个行为动作,
     73     *                 当实现类实现doeat方法时就可以监听到Person类对象eat(吃)这个动作
     74     * @Anthor:孤傲苍狼
     75     *
     76     * @param e
     77     */ 
     78     void doeat(Event e);
     79 
     80     /**
     81     * @Method: dorun
     82     * @Description: 这个方法是用来监听Person对象run(跑)这个行为动作,
     83     *                 当实现类实现dorun方法时就可以监听到Person类对象run(跑)这个动作
     84     * @Anthor:孤傲苍狼
     85     *
     86     * @param e
     87     */ 
     88     void dorun(Event e);
     89 
     90 }
     91 
     92 /**
     93 * @ClassName: Event(事件对象)
     94 * @Description:设计事件类,用来封装事件源
     95 * @author: 孤傲苍狼
     96 * @date: 2014-9-9 下午9:37:56
     97 *
     98 */ 
     99 class Event {
    100 
    101     /**
    102     * @Field: source
    103     *          事件源(Person就是事件源)
    104     */ 
    105     private Person source;
    106 
    107     public Event() {
    108         
    109     }
    110 
    111     public Event(Person source) {
    112         this.source = source;
    113     }
    114 
    115     public Person getSource() {
    116         return source;
    117     }
    118 
    119     public void setSource(Person source) {
    120         this.source = source;
    121     }
    122 }

      经过这样的设计之后,person类的对象就可以被其它对象监听了。测试代码如下:

     1 package me.gacl.observer;
     2 
     3 public class PersonTest {
     4 
     5     /**
     6      * @Method: main
     7      * @Description: 测试Person类
     8      * @Anthor:孤傲苍狼
     9      *
    10      * @param args
    11      */
    12     public static void main(String[] args) {
    13         //
    14         Person p = new Person();
    15         //注册监听p对象行为的监听器
    16         p.registerListener(new PersonListener() {
    17             //监听p吃东西这个行为
    18             public void doeat(Event e) {
    19                 Person p = e.getSource();
    20                 System.out.println(p + "在吃东西");
    21             }
    22             //监听p跑步这个行为
    23             public void dorun(Event e) {
    24                 Person p = e.getSource();
    25                 System.out.println(p + "在跑步");
    26             }
    27         });
    28         //p在吃东西
    29         p.eat();
    30         //p在跑步
    31         p.run();
    32     }
    33 }

      运行结果:

    me.gacl.observer.Person@4a5ab2在吃东西
    me.gacl.observer.Person@4a5ab2在跑步

      

    二、JavaWeb中的监听器

    2.1、基本概念

      JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext、HttpSession和ServletRequest等域对象的创建与销毁事件,以及监听这些域对象中的属性发生修改的事件。

    2.2、Servlet监听器的分类

      在Servlet规范中定义了多种类型的监听器,他们用于监听的事件源分别为ServletContext、HttpSession和ServletRequest这三个域对象。Servlet规范针对这三个对象上的操作,又把多种类型的监听器划分为三种类型:

      1、监听域对象自身的创建和销毁的事件监听器;

      2、监听域对象中的属性的增加和删除的事件监听器;

      3、监听绑定到HttpSession域中的某个对象的状态的事件监听器。

    2.3、监听ServletContext域对象的创建和销毁

      ServletContextListener接口用于监听ServletContext对象的创建和销毁事件。实现了ServletContextListener接口的类都可以对ServletContext对象的创建和销毁进行监听。

      当ServletContext对象被创建时,激发contextInitialized (ServletContextEvent sce)方法。

      当ServletContext对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。

      ServletContext域对象创建和销毁时机:

      创建:服务器启动针对每一个Web应用创建ServletContext

      销毁:服务器关闭前先关闭代表每一个Web应用的ServletContext

     

    范例:编写一个MyServletContextListener类,实现ServletContextListener接口,监听ServletContext对象的创建和销毁

      (1)编写监听器,代码如下:

     1 package me.gacl.web.listener;
     2 
     3 import javax.servlet.ServletContextEvent;
     4 import javax.servlet.ServletContextListener;
     5 
     6 /**
     7 * @ClassName: MyServletContextListener
     8 * @Description: MyServletContextListener类实现了ServletContextListener接口,
     9 *                 因此可以对ServletContext对象的创建和销毁这两个动作进行监听。
    10 * @author: 孤傲苍狼
    11 * @date: 2014-9-9 下午10:26:16
    12 *
    13 */ 
    14 public class MyServletContextListener implements ServletContextListener {
    15 
    16     @Override
    17     public void contextInitialized(ServletContextEvent sce) {
    18         System.out.println("ServletContext对象创建");
    19     }
    20 
    21     @Override
    22     public void contextDestroyed(ServletContextEvent sce) {
    23         System.out.println("ServletContext对象销毁");
    24     }
    25 }

      (2)在web.xml文件中注册监听器

      我们在上面讲到,要想监听事件源,那么必须将监听器注册到事件源上才能够实现对事件源的行为动作进行监听,在JavaWeb中,监听的注册是在web.xml文件中进行配置的,如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <display-name></display-name>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      
      <!-- 注册针对ServletContext对象进行监听的监听器 -->
      <listener>
          <description>ServletContextListener监听器</description>
          <!--实现了ServletContextListener接口的监听器类 -->
          <listener-class>me.gacl.web.listener.MyServletContextListener</listener-class>
      </listener>
      
    </web-app>

      经过这两个步骤,我们就完成了监听器的编写和注册,Web服务器在启动时,就会自动把在web.xml中配置的监听器注册到ServletContext对象上,这样开发好的MyServletContextListener监听器就可以对ServletContext对象进行监听了。

    2.4、监听HttpSession域对象的创建和销毁

      HttpSessionListener 接口用于监听HttpSession对象的创建和销毁
      创建一个Session时,激发sessionCreated (HttpSessionEvent se) 方法
      销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法。

     

    范例:编写一个MyHttpSessionListener类,实现HttpSessionListener接口,监听HttpSession对象的创建和销毁

      (1)编写监听器,代码如下:

     1 package me.gacl.web.listener;
     2 
     3 import javax.servlet.http.HttpSessionEvent;
     4 import javax.servlet.http.HttpSessionListener;
     5 
     6 /**
     7 * @ClassName: MyHttpSessionListener
     8 * @Description: MyHttpSessionListener类实现了HttpSessionListener接口,
     9 *                 因此可以对HttpSession对象的创建和销毁这两个动作进行监听。
    10 * @author: 孤傲苍狼
    11 * @date: 2014-9-9 下午11:04:33
    12 *
    13 */ 
    14 public class MyHttpSessionListener implements HttpSessionListener {
    15 
    16     @Override
    17     public void sessionCreated(HttpSessionEvent se) {
    18         System.out.println( se.getSession() + "创建了!!");
    19         System.out.println("创建好的HttpSession的id是:" + se.getSession().getId());
    20     }
    21 
    22     /* HttpSession的销毁时机需要在web.xml中进行配置,如下:
    23      * <session-config>
    24               <session-timeout>1</session-timeout>
    25           </session-config>
    26           这样配置就表示session在1分钟之后就被销毁
    27      */
    28     @Override
    29     public void sessionDestroyed(HttpSessionEvent se) {
    30         System.out.println("session销毁了!!");
    31     }
    32 }

      (2)web.xml文件中注册监听器

    <!--注册针对HttpSession对象进行监听的监听器-->
       <listener>
          <description>HttpSessionListener监听器</description>
          <listener-class>me.gacl.web.listener.MyHttpSessionListener</listener-class>
      </listener>
      <!-- 配置HttpSession对象的销毁时机 -->
      <session-config>
          <!--配置HttpSession对象的1分钟之后销毁 -->
          <session-timeout>1</session-timeout>
      </session-config>

      当我们访问jsp页面时,HttpSession对象就会创建,此时就可以对HttpSessionListener观察到HttpSession对象的创建过程了。

      运行结果如下:

    2.5、监听ServletRequest域对象的创建和销毁

      ServletRequestListener接口用于监听ServletRequest对象的创建和销毁

      Request对象被创建时,监听器的requestInitialized(ServletRequestEvent sre)方法将会被调用

      Request对象被销毁时,监听器的requestDestroyed(ServletRequestEvent sre)方法将会被调用

      ServletRequest域对象创建和销毁时机:
        创建:用户每一次访问都会创建request对象
        销毁:当前访问结束,request对象就会销毁

     

    范例:编写一个MyServletRequestListener类,实现ServletRequestListener接口,监听ServletRequest对象的创建和销毁

      (1)编写监听器,代码如下:

     1 package me.gacl.web.listener;
     2 
     3 import javax.servlet.ServletRequestEvent;
     4 import javax.servlet.ServletRequestListener;
     5 
     6 /**
     7 * @ClassName: MyServletRequestListener
     8 * @Description: MyServletRequestListener类实现了ServletRequestListener接口,
     9 *                 因此可以对ServletRequest对象的创建和销毁这两个动作进行监听。
    10 * @author: 孤傲苍狼
    11 * @date: 2014-9-9 下午11:50:08
    12 *
    13 */ 
    14 public class MyServletRequestListener implements ServletRequestListener {
    15 
    16     @Override
    17     public void requestDestroyed(ServletRequestEvent sre) {
    18         System.out.println(sre.getServletRequest() + "销毁了!!");
    19         
    20     }
    21 
    22     @Override
    23     public void requestInitialized(ServletRequestEvent sre) {
    24         System.out.println(sre.getServletRequest() + "创建了!!");
    25     }
    26 }

      (2)在web.xml文件中注册监听器

    <!--注册针对ServletRequest对象进行监听的监听器-->
        <listener>
           <description>ServletRequestListener监听器</description>
           <listener-class>me.gacl.web.listener.MyServletRequestListener</listener-class>
       </listener>

      测试结果如下:

       从运行结果中可以看到,用户每一次请求都会创建request对象,当请求结束后,request对象就会销毁。

     

      转载自《javaWeb学习总结(11)- 监听器(Listener)学习

  • 相关阅读:
    循环顺序队列
    iscsi与multipath
    MySQL 数据库设计 笔记与总结(4)维护优化
    [Swift]LeetCode6. Z字形变换 | ZigZag Conversion
    [Swift]八大排序算法(八):基数排序
    [Swift]八大排序算法(七):归并排序
    [Swift]八大排序算法(六):希尔排序
    [Swift]八大排序算法(五):插入排序
    [Swift]八大排序算法(四):堆排序
    [Swift]八大排序算法(三):选择排序 和 简单选择排序
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/10778648.html
Copyright © 2020-2023  润新知