监听器(Listener)学习

2024-05-04 21:58
文章标签 学习 监听器 listener

本文主要是介绍监听器(Listener)学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、监听器介绍

1.1、监听器的概念

  

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

1.2、监听器案例——监听window窗口的事件监听器

复制代码
 1 package me.gacl.listener.demo;
 2 
 3 import java.awt.Frame;
 4 import java.awt.event.WindowEvent;
 5 import java.awt.event.WindowListener;
 6 
 7 public class Demo1 {
 8 
 9     /**
10      *java的事件监听机制
11      *1、事件监听涉及到三个组件:事件源、事件对象、事件监听器
12      *2、当事件源上发生某一个动作时,它会调用事件监听器的一个方法,并在调用该方法时把事件对象传递进去,
13      *    开发人员在监听器中通过事件对象,就可以拿到事件源,从而对事件源进行操作。
14      */
15     public static void main(String[] args) {
16         
17         Frame f = new Frame();
18         f.setSize(400, 400);
19         f.setVisible(true);
20         
21         //注册事件监听器
22         f.addWindowListener(new WindowListener(){
23 
24             public void windowActivated(WindowEvent e) {
25                 
26             }
27 
28             public void windowClosed(WindowEvent e) {
29                 
30             }
31 
32             /**
33              * 当window窗体关闭时就会WindowListener这个监听器监听到,
34              * 监听器就会调用windowClosing方法处理window窗体关闭时的动作
35              */
36             public void windowClosing(WindowEvent e) {
37                 //通过事件对象e来获取事件源对象
38                 Frame f = (Frame) e.getSource();
39                 System.out.println(f+"窗体正在关闭");
40                 f.dispose();
41             }
42 
43             public void windowDeactivated(WindowEvent e) {
44                 
45             }
46 
47             public void windowDeiconified(WindowEvent e) {
48                 
49             }
50 
51             public void windowIconified(WindowEvent e) {
52                 
53             }
54 
55             public void windowOpened(WindowEvent e) {
56                 
57             }
58         });
59     }
60 }
复制代码

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

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

  下面我们来按照事件处理模型来设计一个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 }
复制代码

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

复制代码
 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规范中定义了多种类型的监听器,它们用于监听的事件源分别为ServletContextHttpSessionServletRequest这三个域对象
  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文件中进行配置的,如下:

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="3.0" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 7   <display-name></display-name>    
 8   <welcome-file-list>
 9     <welcome-file>index.jsp</welcome-file>
10   </welcome-file-list>
11   
12   <!-- 注册针对ServletContext对象进行监听的监听器 -->
13   <listener>
14       <description>ServletContextListener监听器</description>
15       <!--实现了ServletContextListener接口的监听器类 -->
16       <listener-class>me.gacl.web.listener.MyServletContextListener</listener-class>
17   </listener>
18   
19 </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     }
20 
21     /* HttpSession的销毁时机需要在web.xml中进行配置,如下:
22      * <session-config>
23               <session-timeout>1</session-timeout>
24           </session-config>
25           这样配置就表示session在1分钟之后就被销毁
26      */
27     @Override
28     public void sessionDestroyed(HttpSessionEvent se) {
29         System.out.println("session销毁了!!");
30     }
31 }
复制代码

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

复制代码
 1  <!--注册针对HttpSession对象进行监听的监听器-->
 2    <listener>
 3       <description>HttpSessionListener监听器</description>
 4       <listener-class>me.gacl.web.listener.MyHttpSessionListener</listener-class>
 5   </listener>
 6   <!-- 配置HttpSession对象的销毁时机 -->
 7   <session-config>
 8       <!--配置HttpSession对象的1分钟之后销毁 -->
 9       <session-timeout>1</session-timeout>
10   </session-config>
复制代码

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

如下:index.jsp

复制代码
 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
 2 
 3 <!DOCTYPE HTML>
 4 <html>
 5   <head>
 6     <title>HttpSessionListener监听器监听HttpSession对象的创建</title>
 7   </head>
 8   
 9   <body>
10        一访问JSP页面,HttpSession就创建了,创建好的Session的Id是:${pageContext.session.id}
11   </body>
12 </html>
复制代码

运行结果如下:

  

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文件中注册监听器

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

测试结果如下:

  

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

  以上就是对监听器的一些简单讲解。

这篇关于监听器(Listener)学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960173

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件