成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

監(jiān)聽器入門看這篇就夠了

eechen / 1317人閱讀

摘要:但監(jiān)聽器要在事件源上實現(xiàn)接口也就是說,直接用一個類實現(xiàn)和接口是監(jiān)聽不到內(nèi)對象的變化的。

什么是監(jiān)聽器
監(jiān)聽器就是一個實現(xiàn)特定接口的普通java程序,這個程序?qū)iT用于監(jiān)聽另一個java對象的方法調(diào)用或?qū)傩愿淖?/strong>,當(dāng)被監(jiān)聽對象發(fā)生上述事件后,監(jiān)聽器某個方法將立即被執(zhí)行。。
為什么我們要使用監(jiān)聽器?

監(jiān)聽器可以用來檢測網(wǎng)站的在線人數(shù),統(tǒng)計網(wǎng)站的訪問量等等

監(jiān)聽器組件

監(jiān)聽器涉及三個組件:事件源,事件對象,事件監(jiān)聽器

當(dāng)事件源發(fā)生某個動作的時候,它會調(diào)用事件監(jiān)聽器的方法,并在調(diào)用事件監(jiān)聽器方法的時候把事件對象傳遞進(jìn)去。

我們在監(jiān)聽器中就可以通過事件對象獲取得到事件源,從而對事件源進(jìn)行操作!

模擬監(jiān)聽器

既然上面已經(jīng)說了監(jiān)聽器的概念了,監(jiān)聽器涉及三個組件:事件源,事件對象,事件監(jiān)聽器。

我們就寫一個對象,被監(jiān)聽器監(jiān)聽

監(jiān)聽器

監(jiān)聽器定義為接口,監(jiān)聽的方法需要事件對象傳遞進(jìn)來,從而在監(jiān)聽器上通過事件對象獲取得到事件源,對事件源進(jìn)行修改!

    /**
     * 事件監(jiān)聽器
     *
     * 監(jiān)聽Person事件源的eat和sleep方法
     */
    interface PersonListener{
    
        void doEat(Event event);
        void doSleep(Event event);
    }
事件源

事件源是一個Person類,它有eat和sleep()方法。

事件源需要注冊監(jiān)聽器(即在事件源上關(guān)聯(lián)監(jiān)聽器對象)

如果觸發(fā)了eat或sleep()方法的時候,會調(diào)用監(jiān)聽器的方法,并將事件對象傳遞進(jìn)去


    /**
     *
     * 事件源Person
     *
     * 事件源要提供方法注冊監(jiān)聽器(即在事件源上關(guān)聯(lián)監(jiān)聽器對象)
     */
    
    class Person {
    
        //在成員變量定義一個監(jiān)聽器對象
        private PersonListener personListener ;
        
        //在事件源中定義兩個方法
        public void Eat() {
            
            //當(dāng)事件源調(diào)用了Eat方法時,應(yīng)該觸發(fā)監(jiān)聽器的方法,調(diào)用監(jiān)聽器的方法并把事件對象傳遞進(jìn)去
            personListener.doEat(new Event(this));
        }
    
        public void sleep() {
    
            //當(dāng)事件源調(diào)用了Eat方法時,應(yīng)該觸發(fā)監(jiān)聽器的方法,調(diào)用監(jiān)聽器的方法并把事件對象傳遞進(jìn)去
            personListener.doSleep(new Event(this));
        }
    
        //注冊監(jiān)聽器,該類沒有監(jiān)聽器對象啊,那么就傳遞進(jìn)來吧。
        public void registerLister(PersonListener personListener) {
            this.personListener = personListener;
        }
    
    }

事件對象

事件對象封裝了事件源。

監(jiān)聽器可以從事件對象上獲取得到事件源的對象(信息)



    /**
     * 事件對象Even
     *
     * 事件對象封裝了事件源
     *
     * 在監(jiān)聽器上能夠通過事件對象獲取得到事件源
     *
     *
     */
    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();

        //注冊監(jiān)聽器()
        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 + "正在睡覺呢!");
            }
        });


        //當(dāng)調(diào)用eat方法時,觸發(fā)事件,將事件對象傳遞給監(jiān)聽器,最后監(jiān)聽器獲得事件源,對事件源進(jìn)行操作
        person.Eat();
    }

事件源:擁有事件

監(jiān)聽器:監(jiān)聽事件源所擁有的事件(帶事件對象參數(shù)的)

事件對象:事件對象封裝了事件源對象

事件源要與監(jiān)聽器有關(guān)系,就得注冊監(jiān)聽器【提供方法得到監(jiān)聽器對象】

觸發(fā)事件源的事件,實際會提交給監(jiān)聽器對象處理,并且把事件對象傳遞過去給監(jiān)聽器。

Servle監(jiān)聽器

在Servlet規(guī)范中定義了多種類型的監(jiān)聽器,它們用于監(jiān)聽的事件源分別 ServletContext, HttpSession和ServletRequest這三個域?qū)ο?/strong>

和其它事件監(jiān)聽器略有不同的是,servlet監(jiān)聽器的注冊不是直接注冊在事件源上,而是由WEB容器負(fù)責(zé)注冊,開發(fā)人員只需在web.xml文件中使用標(biāo)簽配置好監(jiān)聽器

監(jiān)聽對象的創(chuàng)建和銷毀

HttpSessionListener、ServletContextListener、ServletRequestListener分別監(jiān)控著Session、Context、Request對象的創(chuàng)建和銷毀

HttpSessionListener(可以用來收集在線者信息)

ServletContextListener(可以獲取web.xml里面的參數(shù)配置)

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("容器創(chuàng)建了");
    }

    public void contextDestroyed(ServletContextEvent sce) {

        System.out.println("容器銷毀了");
    }


    public void sessionCreated(HttpSessionEvent se) {

        System.out.println("Session創(chuàng)建了");
    }

    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("Session銷毀了");
    }


    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {

    }
}

監(jiān)聽器監(jiān)聽到ServletContext的初始化了,Session的創(chuàng)建和ServletContext的銷毀。(服務(wù)器停掉,不代表Session就被銷毀了。Session的創(chuàng)建是在內(nèi)存中的,所以沒看到Session被銷毀了)

監(jiān)聽對象屬性變化

ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener分別監(jiān)聽著Context、Session、Request對象屬性的變化

這三個接口中都定義了三個方法來處理被監(jiān)聽對象中的屬性的增加,刪除和替換的事件,同一個事件在這三個接口中對應(yīng)的方法名稱完全相同,只是接受的參數(shù)類型不同

attributeAdded()

attributeRemoved()

attributeReplaced()

測試

這里我只演示Context對象,其他對象都是以此類推的,就不一一測試了

實現(xiàn)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");
        
    }

監(jiān)聽Session內(nèi)的對象

除了上面的6種Listener,還有兩種Linstener監(jiān)聽Session內(nèi)的對象,分別是HttpSessionBindingListener和HttpSessionActivationListener,實現(xiàn)這兩個接口并不需要在web.xml文件中注冊

實現(xiàn)HttpSessionBindingListener接口,JavaBean 對象可以感知自己被綁定到 Session 中和從 Session 中刪除的事件【和HttpSessionAttributeListener的作用是差不多的】

實現(xiàn)HttpSessionActivationListener接口,JavaBean 對象可以感知自己被活化和鈍化的事件(當(dāng)服務(wù)器關(guān)閉時,會將Session的內(nèi)容保存在硬盤上【鈍化】,當(dāng)服務(wù)器開啟時,會將Session的內(nèi)容在硬盤式重新加載【活化】) 。。

想要測試出Session的硬化和鈍化,需要修改Tomcat的配置的。在META-INF下的context.xml文件中添加下面的代碼:


  
  
  

測試

監(jiān)聽器和事件源


/*
* 由于涉及到了將內(nèi)存的Session鈍化到硬盤和用硬盤活化到內(nèi)存中,所以需要實現(xiàn)Serializable接口
*
* 該監(jiān)聽器是不需要在web.xml文件中配置的。但監(jiān)聽器要在事件源上實現(xiàn)接口
* 也就是說,直接用一個類實現(xiàn)HttpSessionBindingListener和HttpSessionActivationListener接口是監(jiān)聽不到Session內(nèi)對象的變化的。
* 因為它們是感知自己在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");

效果:

如果文章有錯的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號:Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/70957.html

相關(guān)文章

  • JS正則表達(dá)式入門,看這篇就夠了

    摘要:如果遇到非常的復(fù)雜的匹配,正則表達(dá)式的優(yōu)勢就更加明顯了。關(guān)于正則表達(dá)式書寫規(guī)則,可查看,上面說的很清楚了,我就不貼出來了。替換與正則表達(dá)式匹配的子串,并返回替換后的字符串。結(jié)語正則表達(dá)式并不難,懂了其中的套路之后,一切都變得簡單了。 前言 在正文開始前,先說說正則表達(dá)式是什么,為什么要用正則表達(dá)式?正則表達(dá)式在我個人看來就是一個瀏覽器可以識別的規(guī)則,有了這個規(guī)則,瀏覽器就可以幫我們判斷...

    wenzi 評論0 收藏0
  • ES6入門,看這篇就夠了

    摘要:從入門到放棄是什么,黑歷史,不講,自己百度去。類你沒有看錯,這里面的就沒有問題的。之前我們用過,和有了,再也不用這兩個貨了。一個函數(shù),可以遍歷狀態(tài)感覺就是狀態(tài)機(jī),好吧不說了再說就懵逼了。 ES6從入門到放棄 1.ES6是什么,黑歷史,不講,自己百度去。 2.在瀏覽器中如何使用? 1.babel babeljs.io在線編譯 2.traceur-----Google出的編譯器,把E...

    lewinlee 評論0 收藏0
  • Lombok 看這篇就夠了

    摘要:注解在類上為類提供一個全參的構(gòu)造方法,加了這個注解后,類中不提供默認(rèn)構(gòu)造方法了。這個注解用在類上,使用類中所有帶有注解的或者帶有修飾的成員變量生成對應(yīng)的構(gòu)造方法。 轉(zhuǎn)載請注明原創(chuàng)地址:http://www.54tianzhisheng.cn/2018/01/07/lombok/ showImg(http://ohfk1r827.bkt.clouddn.com/blog/180107/7...

    LeanCloud 評論0 收藏0
  • Python 3 入門看這篇就夠了

    摘要:縮進(jìn)不一致,會導(dǎo)致運行錯誤。變量變量在使用前必須先定義即賦予變量一個值,否則會報錯數(shù)據(jù)類型布爾只有和兩個值,表示真或假。 簡介 Python 是一種高層次的結(jié)合了解釋性、編譯性、互動性和面向?qū)ο蟮哪_本語言。Python 由 Guido van Rossum 于 1989 年底在荷蘭國家數(shù)學(xué)和計算機(jī)科學(xué)研究所發(fā)明,第一個公開發(fā)行版發(fā)行于 1991 年。 特點 易于學(xué)習(xí):Python ...

    Shimmer 評論0 收藏0
  • 你真的完全了解Java動態(tài)代理嗎?看這篇就夠了

    摘要:動態(tài)地代理,可以猜測一下它的含義,在運行時動態(tài)地對某些東西代理,代理它做了其他事情。所以動態(tài)代理的內(nèi)容重點就是這個。所以下一篇我們來細(xì)致了解下的到底是怎么使用動態(tài)代理的。 之前講了《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》,本來打算下一篇講講Srping的AOP的,但是其中會涉及到Java的動態(tài)代理,所以先單獨一篇來了解下Java的動態(tài)代理到底是什么,Java是怎么實現(xiàn)它的。 ...

    haitiancoder 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<