摘要:但監聽器要在事件源上實現接口也就是說,直接用一個類實現和接口是監聽不到內對象的變化的。
什么是監聽器
監聽器就是一個實現特定接口的普通java程序,這個程序專門用于監聽另一個java對象的方法調用或屬性改變,當被監聽對象發生上述事件后,監聽器某個方法將立即被執行。。為什么我們要使用監聽器?
監聽器可以用來檢測網站的在線人數,統計網站的訪問量等等!
監聽器組件監聽器涉及三個組件:事件源,事件對象,事件監聽器
當事件源發生某個動作的時候,它會調用事件監聽器的方法,并在調用事件監聽器方法的時候把事件對象傳遞進去。
我們在監聽器中就可以通過事件對象獲取得到事件源,從而對事件源進行操作!
模擬監聽器既然上面已經說了監聽器的概念了,監聽器涉及三個組件:事件源,事件對象,事件監聽器。
我們就寫一個對象,被監聽器監聽
監聽器監聽器定義為接口,監聽的方法需要事件對象傳遞進來,從而在監聽器上通過事件對象獲取得到事件源,對事件源進行修改!
/** * 事件監聽器 * * 監聽Person事件源的eat和sleep方法 */ interface PersonListener{ void doEat(Event event); void doSleep(Event event); }事件源
事件源是一個Person類,它有eat和sleep()方法。
事件源需要注冊監聽器(即在事件源上關聯監聽器對象)
如果觸發了eat或sleep()方法的時候,會調用監聽器的方法,并將事件對象傳遞進去
/** * * 事件源Person * * 事件源要提供方法注冊監聽器(即在事件源上關聯監聽器對象) */ class Person { //在成員變量定義一個監聽器對象 private PersonListener personListener ; //在事件源中定義兩個方法 public void Eat() { //當事件源調用了Eat方法時,應該觸發監聽器的方法,調用監聽器的方法并把事件對象傳遞進去 personListener.doEat(new Event(this)); } public void sleep() { //當事件源調用了Eat方法時,應該觸發監聽器的方法,調用監聽器的方法并把事件對象傳遞進去 personListener.doSleep(new Event(this)); } //注冊監聽器,該類沒有監聽器對象啊,那么就傳遞進來吧。 public void registerLister(PersonListener personListener) { this.personListener = personListener; } }事件對象
事件對象封裝了事件源。
監聽器可以從事件對象上獲取得到事件源的對象(信息)
/** * 事件對象Even * * 事件對象封裝了事件源 * * 在監聽器上能夠通過事件對象獲取得到事件源 * * */ class Event{ private Person person; public Event() { } public Event(Person person) { this.person = person; } public Person getResource() { return person; } }測試
public static void main(String[] args) { Person person = new Person(); //注冊監聽器() person.registerLister(new PersonListener() { @Override public void doEat(Event event) { Person person1 = event.getResource(); System.out.println(person1 + "正在吃飯呢!"); } @Override public void doSleep(Event event) { Person person1 = event.getResource(); System.out.println(person1 + "正在睡覺呢!"); } }); //當調用eat方法時,觸發事件,將事件對象傳遞給監聽器,最后監聽器獲得事件源,對事件源進行操作 person.Eat(); }
事件源:擁有事件
監聽器:監聽事件源所擁有的事件(帶事件對象參數的)
事件對象:事件對象封裝了事件源對象
事件源要與監聽器有關系,就得注冊監聽器【提供方法得到監聽器對象】
觸發事件源的事件,實際會提交給監聽器對象處理,并且把事件對象傳遞過去給監聽器。
Servle監聽器在Servlet規范中定義了多種類型的監聽器,它們用于監聽的事件源分別 ServletContext, HttpSession和ServletRequest這三個域對象
和其它事件監聽器略有不同的是,servlet監聽器的注冊不是直接注冊在事件源上,而是由WEB容器負責注冊,開發人員只需在web.xml文件中使用
HttpSessionListener、ServletContextListener、ServletRequestListener分別監控著Session、Context、Request對象的創建和銷毀
HttpSessionListener(可以用來收集在線者信息)
ServletContextListener(可以獲取web.xml里面的參數配置)
ServletRequestListener
測試public class Listener1 implements ServletContextListener, HttpSessionListener, ServletRequestListener { // Public constructor is required by servlet spec public Listener1() { } public void contextInitialized(ServletContextEvent sce) { System.out.println("容器創建了"); } public void contextDestroyed(ServletContextEvent sce) { System.out.println("容器銷毀了"); } public void sessionCreated(HttpSessionEvent se) { System.out.println("Session創建了"); } public void sessionDestroyed(HttpSessionEvent se) { System.out.println("Session銷毀了"); } @Override public void requestDestroyed(ServletRequestEvent servletRequestEvent) { } @Override public void requestInitialized(ServletRequestEvent servletRequestEvent) { } }
監聽器監聽到ServletContext的初始化了,Session的創建和ServletContext的銷毀。(服務器停掉,不代表Session就被銷毀了。Session的創建是在內存中的,所以沒看到Session被銷毀了)
監聽對象屬性變化ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener分別監聽著Context、Session、Request對象屬性的變化
這三個接口中都定義了三個方法來處理被監聽對象中的屬性的增加,刪除和替換的事件,同一個事件在這三個接口中對應的方法名稱完全相同,只是接受的參數類型不同。
attributeAdded()
attributeRemoved()
attributeReplaced()
測試這里我只演示Context對象,其他對象都是以此類推的,就不一一測試了。
實現ServletContextAttributeListener接口。
public class Listener1 implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("Context對象增加了屬性"); } @Override public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("Context對象刪除了屬性"); } @Override public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) { System.out.println("Context對象替換了屬性"); } }
測試的Servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); context.setAttribute("aa", "123"); context.setAttribute("aa", "234"); context.removeAttribute("aa"); }監聽Session內的對象
除了上面的6種Listener,還有兩種Linstener監聽Session內的對象,分別是HttpSessionBindingListener和HttpSessionActivationListener,實現這兩個接口并不需要在web.xml文件中注冊
實現HttpSessionBindingListener接口,JavaBean 對象可以感知自己被綁定到 Session 中和從 Session 中刪除的事件【和HttpSessionAttributeListener的作用是差不多的】
實現HttpSessionActivationListener接口,JavaBean 對象可以感知自己被活化和鈍化的事件(當服務器關閉時,會將Session的內容保存在硬盤上【鈍化】,當服務器開啟時,會將Session的內容在硬盤式重新加載【活化】) 。。
想要測試出Session的硬化和鈍化,需要修改Tomcat的配置的。在META-INF下的context.xml文件中添加下面的代碼:
測試
監聽器和事件源
/* * 由于涉及到了將內存的Session鈍化到硬盤和用硬盤活化到內存中,所以需要實現Serializable接口 * * 該監聽器是不需要在web.xml文件中配置的。但監聽器要在事件源上實現接口 * 也就是說,直接用一個類實現HttpSessionBindingListener和HttpSessionActivationListener接口是監聽不到Session內對象的變化的。 * 因為它們是感知自己在Session中的變化! * */ public class User implements HttpSessionBindingListener,HttpSessionActivationListener,Serializable { private String username ; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) { HttpSession httpSession = httpSessionEvent.getSession(); System.out.println("鈍化了"); } @Override public void sessionDidActivate(HttpSessionEvent httpSessionEvent) { HttpSession httpSession = httpSessionEvent.getSession(); System.out.println("活化了"); } @Override public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("綁定了對象"); } @Override public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) { System.out.println("解除了對象"); } }
測試代碼
User user = new User(); request.getSession().setAttribute("aaa", user); request.getSession().removeAttribute("aaa");
效果:
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章的同學,可以關注微信公眾號:Java3y
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70957.html
摘要:如果遇到非常的復雜的匹配,正則表達式的優勢就更加明顯了。關于正則表達式書寫規則,可查看,上面說的很清楚了,我就不貼出來了。替換與正則表達式匹配的子串,并返回替換后的字符串。結語正則表達式并不難,懂了其中的套路之后,一切都變得簡單了。 前言 在正文開始前,先說說正則表達式是什么,為什么要用正則表達式?正則表達式在我個人看來就是一個瀏覽器可以識別的規則,有了這個規則,瀏覽器就可以幫我們判斷...
摘要:從入門到放棄是什么,黑歷史,不講,自己百度去。類你沒有看錯,這里面的就沒有問題的。之前我們用過,和有了,再也不用這兩個貨了。一個函數,可以遍歷狀態感覺就是狀態機,好吧不說了再說就懵逼了。 ES6從入門到放棄 1.ES6是什么,黑歷史,不講,自己百度去。 2.在瀏覽器中如何使用? 1.babel babeljs.io在線編譯 2.traceur-----Google出的編譯器,把E...
摘要:注解在類上為類提供一個全參的構造方法,加了這個注解后,類中不提供默認構造方法了。這個注解用在類上,使用類中所有帶有注解的或者帶有修飾的成員變量生成對應的構造方法。 轉載請注明原創地址:http://www.54tianzhisheng.cn/2018/01/07/lombok/ showImg(http://ohfk1r827.bkt.clouddn.com/blog/180107/7...
摘要:縮進不一致,會導致運行錯誤。變量變量在使用前必須先定義即賦予變量一個值,否則會報錯數據類型布爾只有和兩個值,表示真或假。 簡介 Python 是一種高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言。Python 由 Guido van Rossum 于 1989 年底在荷蘭國家數學和計算機科學研究所發明,第一個公開發行版發行于 1991 年。 特點 易于學習:Python ...
摘要:動態地代理,可以猜測一下它的含義,在運行時動態地對某些東西代理,代理它做了其他事情。所以動態代理的內容重點就是這個。所以下一篇我們來細致了解下的到底是怎么使用動態代理的。 之前講了《零基礎帶你看Spring源碼——IOC控制反轉》,本來打算下一篇講講Srping的AOP的,但是其中會涉及到Java的動態代理,所以先單獨一篇來了解下Java的動態代理到底是什么,Java是怎么實現它的。 ...
閱讀 1614·2021-11-16 11:45
閱讀 2544·2021-09-29 09:48
閱讀 3269·2021-09-07 10:26
閱讀 1840·2021-08-16 10:50
閱讀 1866·2019-08-30 15:44
閱讀 2698·2019-08-28 18:03
閱讀 1898·2019-08-27 10:54
閱讀 1823·2019-08-26 14:01