JavaWeb監(jiān)聽(tīng)器Listener實(shí)例解析
首先來(lái)介紹一下什么是監(jiān)聽(tīng)器:
監(jiān)聽(tīng)器-就是一個(gè)實(shí)現(xiàn)待定接口的普通Java程序,此程序?qū)iT用于監(jiān)聽(tīng)另外一個(gè)類的方法調(diào)用。
這是使用觀察者模式的。
什么是觀察者模式:
定義對(duì)象間一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知自動(dòng)更新。
示例:
GUI編程中的addXxxxListener都是觀察者模式。
比如為按鈕點(diǎn)擊添加監(jiān)聽(tīng)事件,為鍵盤添加監(jiān)聽(tīng)等等…
觀察者模式的三個(gè)重要類:

被監(jiān)聽(tīng)的事件源,也就是我們?cè)谑褂玫膶?duì)象。
注冊(cè)的那個(gè)監(jiān)聽(tīng)器,是專門用來(lái)監(jiān)聽(tīng)當(dāng)前使用的對(duì)象的。
事件對(duì)象Event也就是被監(jiān)聽(tīng)的那個(gè)對(duì)象!
我們先來(lái)看一個(gè)簡(jiǎn)單版的,自己寫的監(jiān)聽(tīng)器。
簡(jiǎn)單版:
有事件源,和監(jiān)聽(tīng)器,測(cè)試類.
Event等下一個(gè)完整版實(shí)現(xiàn).
開(kāi)發(fā)步驟:
第一步:實(shí)現(xiàn)一個(gè)需要被監(jiān)聽(tīng)的類Person.
第二步:實(shí)現(xiàn)一個(gè)監(jiān)聽(tīng)接口IPersonRunListener。
第三步:在Person類中,提供一個(gè)方法(或者多個(gè),我在這里提供了2個(gè)方法)用于注冊(cè)IPersonRunListener類,即addBefore和addAfter
第四步:必須要在Person類中維護(hù)IPersonRunListener類的實(shí)例。
第五步:在調(diào)用person.run方法時(shí),判斷IPersonRunListener是否為null,如果不為null則調(diào)用它的fighting方法。
第六步:在Demo類中,實(shí)例化Person,并注冊(cè)一個(gè)監(jiān)聽(tīng)。
Person:
package cn.hncu.designPattern1;
public class Person {
private String name;
private IPersonRunListener listener1;
private IPersonRunListener listener2;
public Person(String name) {
super();
this.name = name;
}
public void run(){
if(listener1!=null){
listener1.fighting();
}
System.out.println(name+"正在跑...");
if(listener2!=null){
listener2.fighting();
}
}
public void addBefore(IPersonRunListener listener){
this.listener1=listener;
}
public void addAfter(IPersonRunListener listener){
this.listener2=listener;
}
}
interface IPersonRunListener{
public void fighting();
}
Demo
package cn.hncu.designPattern1;
public class Demo {
public static void main(String[] args) {
Person person = new Person("張三");
IPersonRunListener listener = new IPersonRunListener() {
@Override
public void fighting() {
//這里可以做很多事,不是只能輸出哦
//不過(guò)由于還沒(méi)寫Event對(duì)象,所以拿不到是誰(shuí)調(diào)用的
System.out.println("先做好準(zhǔn)備工作...");
}
};
person.addBefore(listener);
A a = new A();
person.addAfter(a);
person.run();
}
}
class A implements IPersonRunListener{
@Override
public void fighting() {
//這里可以做很多事,不是只能輸出哦
//不過(guò)由于還沒(méi)寫Event對(duì)象,所以拿不到是誰(shuí)調(diào)用的
System.out.println("跑完了,休息休息...");
}
}
輸出:

完整版–添加事件源:
在這里相對(duì)前面的增加了一個(gè)Event-事件對(duì)象.算是完整版的了。
開(kāi)發(fā)步驟:
第一步:在前頁(yè)的基礎(chǔ)上繼續(xù)添加一個(gè)PersonEvent類(注意我說(shuō)是類不是接口),代表事件對(duì)像。
第二步:給PersonEvent對(duì)像,添加一個(gè)Person屬性,用以標(biāo)識(shí)事件源對(duì)像。
第三步:修改PersonListener接口的fighting方法,讓它接收一個(gè)PersonEvent參數(shù)。
第四步:在Person類run方法中,如果判斷PersonListener屬性不為空,則在調(diào)用fighting方法,實(shí)例化PersonEvent并傳給fighting方法。
第五步:在main方法中,通過(guò)PersonEvent的getSource方法測(cè)試是否是同一個(gè)對(duì)像。
Person.java
package cn.hncu.designPattern2;
public class Person {
private String name;
private IPersonRunListener listener;
public Person(String name) {
super();
this.name = name;
}
public void run(){
System.out.println(name+"開(kāi)始跑了..");
if(listener!=null){
listener.fighting(new PersonEvent(this));
}
}
public void addPersonListener(IPersonRunListener listener){
this.listener=listener;
}
public String getName(){
return name;
}
@Override
public String toString() {
return "Person [name=" + name + ", listener=" + listener + "]";
}
}
interface IPersonRunListener {
public void fighting(PersonEvent pe);
}
class PersonEvent{
Person p = null;
public PersonEvent(Person p) {
this.p = p;
}
public String getName(){
return p.getName();
}
public Object getSource(){
return p;
}
}
//我們還可以寫一個(gè)幫我們實(shí)現(xiàn)了接口的基本類
//里面寫我們通用的模板,如果我們繼承這個(gè)類,我們就可以不寫了。
//有功能不一樣的地方,我們就自己寫,覆蓋這個(gè)類的方法
class DefaultCatListener implements IPersonRunListener {
@Override
public void fighting(PersonEvent pe) {
System.out.println("默認(rèn)的動(dòng)作...");
}
}
Demo.java
package cn.hncu.designPattern2;
public class Demo {
public static void main(String[] args) {
Person p1 = new Person("張三");
Person p2 = new Person("Jack");
IPersonRunListener listener = new IPersonRunListener() {
@Override
public void fighting(PersonEvent pe) {
System.out.println(pe.getSource()+"已經(jīng)跑完了...");
if(pe.getName().equals("張三")){
System.out.println(pe.getName()+"跑到了第一名...");
}
}
};
p1.addPersonListener(listener);
p2.addPersonListener(listener);
p1.run();
p2.run();
Person p3 = new Person("李四");
p3.addPersonListener(new DefaultCatListener());
p3.run();
}
}
演示結(jié)果:

基本上的原理就是這些了,里面事件的輸出你換成你需要的動(dòng)作就可以實(shí)現(xiàn)你想要的功能,添加一個(gè)監(jiān)聽(tīng),就可以在run方法之前或者之后調(diào)用自己想要調(diào)用的方法,做自己想做的動(dòng)作!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 深入了解Java中的過(guò)濾器Filter和監(jiān)聽(tīng)器Listener
- Java監(jiān)聽(tīng)器ActionListener與MouseListener的執(zhí)行順序說(shuō)明
- Java Web監(jiān)聽(tīng)器Listener接口原理及用法實(shí)例
- Java Swing中JList選擇事件監(jiān)聽(tīng)器ListSelectionListener用法示例
- 快速學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法
- 深入學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法
- Java Listener監(jiān)聽(tīng)器使用規(guī)范詳細(xì)介紹
相關(guān)文章
Springboot中com.mysql.cj.jdbc.Driver在yml文件中爆紅的原因解讀
這篇文章主要介紹了Springboot中com.mysql.cj.jdbc.Driver在yml文件中爆紅的原因解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
Java編程技巧:if-else優(yōu)化實(shí)踐總結(jié)歸納
這篇文章主要介紹了Java中避免過(guò)多if-else的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2021-06-06
Spring實(shí)戰(zhàn)之獲得Bean本身的id操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之獲得Bean本身的id操作,結(jié)合實(shí)例形式分析了spring獲取Bean本身id的相關(guān)配置與實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-11-11
Java?synchronized底層實(shí)現(xiàn)原理以及鎖優(yōu)化
Synchronized是Java中解決并發(fā)問(wèn)題的一種最常用的方法,也是最簡(jiǎn)單的一種方法,下面這篇文章主要給大家介紹了關(guān)于Java?synchronized底層實(shí)現(xiàn)原理以及鎖優(yōu)化的相關(guān)資料,需要的朋友可以參考下2022-02-02
SpringBoot整合Mybatis與MybatisPlus方法詳細(xì)講解
這篇文章主要介紹了SpringBoot整合Mybatis與MybatisPlus方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
java 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-09-09
SpringBoot整合MyBatisPlus配置動(dòng)態(tài)數(shù)據(jù)源的方法
這篇文章主要介紹了SpringBoot整合MyBatisPlus配置動(dòng)態(tài)數(shù)據(jù)源的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05
java通過(guò)snmp協(xié)議獲取物理設(shè)備信息
這篇文章主要介紹了java通過(guò)snmp協(xié)議獲取物理設(shè)備信息,snmp中文含義是簡(jiǎn)單網(wǎng)絡(luò)管理協(xié)議,可用完成對(duì)計(jì)算機(jī)、路由器和其他網(wǎng)絡(luò)設(shè)備的遠(yuǎn)程管理和監(jiān)視,本文我們是通過(guò)java程序來(lái)獲取,需要的朋友可以參考下2023-07-07

