JavaWeb監(jiān)聽器Listener實例解析
首先來介紹一下什么是監(jiān)聽器:
監(jiān)聽器-就是一個實現(xiàn)待定接口的普通Java程序,此程序?qū)iT用于監(jiān)聽另外一個類的方法調(diào)用。
這是使用觀察者模式的。
什么是觀察者模式:
定義對象間一對多的依賴關(guān)系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知自動更新。
示例:
GUI編程中的addXxxxListener都是觀察者模式。
比如為按鈕點擊添加監(jiān)聽事件,為鍵盤添加監(jiān)聽等等…
觀察者模式的三個重要類:
被監(jiān)聽的事件源,也就是我們在使用的對象。
注冊的那個監(jiān)聽器,是專門用來監(jiān)聽當前使用的對象的。
事件對象Event也就是被監(jiān)聽的那個對象!
我們先來看一個簡單版的,自己寫的監(jiān)聽器。
簡單版:
有事件源,和監(jiān)聽器,測試類.
Event等下一個完整版實現(xiàn).
開發(fā)步驟:
第一步:實現(xiàn)一個需要被監(jiān)聽的類Person.
第二步:實現(xiàn)一個監(jiān)聽接口IPersonRunListener。
第三步:在Person類中,提供一個方法(或者多個,我在這里提供了2個方法)用于注冊IPersonRunListener類,即addBefore和addAfter
第四步:必須要在Person類中維護IPersonRunListener類的實例。
第五步:在調(diào)用person.run方法時,判斷IPersonRunListener是否為null,如果不為null則調(diào)用它的fighting方法。
第六步:在Demo類中,實例化Person,并注冊一個監(jiān)聽。
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() { //這里可以做很多事,不是只能輸出哦 //不過由于還沒寫Event對象,所以拿不到是誰調(diào)用的 System.out.println("先做好準備工作..."); } }; person.addBefore(listener); A a = new A(); person.addAfter(a); person.run(); } } class A implements IPersonRunListener{ @Override public void fighting() { //這里可以做很多事,不是只能輸出哦 //不過由于還沒寫Event對象,所以拿不到是誰調(diào)用的 System.out.println("跑完了,休息休息..."); } }
輸出:
完整版–添加事件源:
在這里相對前面的增加了一個Event-事件對象.算是完整版的了。
開發(fā)步驟:
第一步:在前頁的基礎(chǔ)上繼續(xù)添加一個PersonEvent類(注意我說是類不是接口),代表事件對像。
第二步:給PersonEvent對像,添加一個Person屬性,用以標識事件源對像。
第三步:修改PersonListener接口的fighting方法,讓它接收一個PersonEvent參數(shù)。
第四步:在Person類run方法中,如果判斷PersonListener屬性不為空,則在調(diào)用fighting方法,實例化PersonEvent并傳給fighting方法。
第五步:在main方法中,通過PersonEvent的getSource方法測試是否是同一個對像。
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+"開始跑了.."); 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; } } //我們還可以寫一個幫我們實現(xiàn)了接口的基本類 //里面寫我們通用的模板,如果我們繼承這個類,我們就可以不寫了。 //有功能不一樣的地方,我們就自己寫,覆蓋這個類的方法 class DefaultCatListener implements IPersonRunListener { @Override public void fighting(PersonEvent pe) { System.out.println("默認的動作..."); } }
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é)果:
基本上的原理就是這些了,里面事件的輸出你換成你需要的動作就可以實現(xiàn)你想要的功能,添加一個監(jiān)聽,就可以在run方法之前或者之后調(diào)用自己想要調(diào)用的方法,做自己想做的動作!
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot中com.mysql.cj.jdbc.Driver在yml文件中爆紅的原因解讀
這篇文章主要介紹了Springboot中com.mysql.cj.jdbc.Driver在yml文件中爆紅的原因解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05Java編程技巧:if-else優(yōu)化實踐總結(jié)歸納
這篇文章主要介紹了Java中避免過多if-else的幾種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2021-06-06Spring實戰(zhàn)之獲得Bean本身的id操作示例
這篇文章主要介紹了Spring實戰(zhàn)之獲得Bean本身的id操作,結(jié)合實例形式分析了spring獲取Bean本身id的相關(guān)配置與實現(xiàn)技巧,需要的朋友可以參考下2019-11-11Java?synchronized底層實現(xiàn)原理以及鎖優(yōu)化
Synchronized是Java中解決并發(fā)問題的一種最常用的方法,也是最簡單的一種方法,下面這篇文章主要給大家介紹了關(guān)于Java?synchronized底層實現(xiàn)原理以及鎖優(yōu)化的相關(guān)資料,需要的朋友可以參考下2022-02-02SpringBoot整合Mybatis與MybatisPlus方法詳細講解
這篇文章主要介紹了SpringBoot整合Mybatis與MybatisPlus方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01java 數(shù)據(jù)結(jié)構(gòu)二叉樹的實現(xiàn)代碼
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)二叉樹的實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-09-09SpringBoot整合MyBatisPlus配置動態(tài)數(shù)據(jù)源的方法
這篇文章主要介紹了SpringBoot整合MyBatisPlus配置動態(tài)數(shù)據(jù)源的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-05-05java通過snmp協(xié)議獲取物理設(shè)備信息
這篇文章主要介紹了java通過snmp協(xié)議獲取物理設(shè)備信息,snmp中文含義是簡單網(wǎng)絡(luò)管理協(xié)議,可用完成對計算機、路由器和其他網(wǎng)絡(luò)設(shè)備的遠程管理和監(jiān)視,本文我們是通過java程序來獲取,需要的朋友可以參考下2023-07-07