springboot源碼分析(四)-監聽器實現原理(上)


開篇之前先把祖師爺搬出來
  費玉清:問大家一個腦筋急轉彎,女人生孩子,用一個成語來形容這一現象
      思考。。。
      思考。。。
      思考。。。
  揭曉謎底: 血口噴人
  反正謎底我已經揭曉了,至於大家能不能看到,我就不管了,哈哈
 

概述

  監聽器,在很多的源碼中都非常的常見,之后我會寫一個nacos源碼分析的文章,那里面也用了很多的監聽器,為什么要使用監聽器,舉個例子,大家在過紅綠燈的時候,每一個司機其實就是一個觀察者,那觀察的目標是什么呢?觀察的目標就是紅綠燈,那這個過程中會產生什么事件呢?就是紅燈,黃燈,綠燈的事件,當司機收到這些事件之后會做出不同的舉動。那如果不使用這種模式,就是我不用紅綠燈,我直接找個交警去一個司機一個司機通知,告訴每個司機,你可以走了,你不能走,比較一下大家就可以發現第一種方式效率更高。其實上面的紅綠燈的場景就是一個典型的監聽器模式,是23中設計模式中的一種,要想搞明白springboot中的監聽器原理,就要先搞清楚監聽器模式原理,所以本篇文章就先介紹設計模式之-監聽器模式。

 

監聽器模式核心組成部分

目標:這個很難解釋,我就把比較官方的話貼出來吧,大家看完例子之后回頭看看官方的定義,目標被觀察的對象,在目標中定義了一個觀察者集合,提供一系列方法可以增加或者刪除觀察者,同時定義了通知觀察者的方法,目標類可以是接口或者抽象類或者具體類。

具體目標:是目標類的字類

Observer:觀察者,對觀察目標的改變做出反應,觀察者一般定義為接口

ConcreteObserver:具體觀察者,和具體的目標狀態綁定

看這些概念很頭大,下面看一個具體的例子

 

觀察者

package com.example.demo.event;

/**
 * @author steve
 * @date 2020/6/3 3:02 下午
 */
public interface WeekendListener {

    public void onEvent(WeekendEvent event);
}

具體觀察者

public class SleepListener implements WeekendListener{
    @Override
    public void onEvent(WeekendEvent event) {
        if (event instanceof SleepEvent){
            System.out.println("hello,"+event.getName());
        }
    }
}

具體觀察者

public class ShoppingListener implements WeekendListener{
    @Override
    public void onEvent(WeekendEvent event) {
        if (event instanceof ShoppingEvent){
            System.out.println("hello, "+event.getName());
        }
    }
}

事件

public class ShoppingEvent implements WeekendEvent{
    @Override
    public String getName() {
        return "shopping";
    }
}

事件

public class SleepEvent implements WeekendEvent{
    @Override
    public String getName() {
        return "sleep";
    }
}

目標

public abstract class AbstractEventtMulticaster {

    public List<WeekendListener> listeners ;

    public AbstractEventtMulticaster(List<WeekendListener> listeners){
        this.listeners = new ArrayList<>(listeners);
    }

    public void multicaster(WeekendEvent event){
        doStart();
        listeners.stream().forEach(l -> l.onEvent(event));
        doEnd();
    }

    public void addListener(WeekendListener listener){
        listeners.add(listener);
    }

    public void removeListener(WeekendListener listener){
        listeners.remove(listener);
    }

    abstract public void doStart();

    abstract public void doEnd();
}

具體目標

public class SimpleEventMulticaster extends AbstractEventtMulticaster{

    public SimpleEventMulticaster(List<WeekendListener> listeners) {
        super(listeners);
    }

    @Override
    public void doStart() {
        System.out.println("start 搞事情");
    }

    @Override
    public void doEnd() {
        System.out.println("end 搞事情");
    }
}

測試

public class Test {

    public static void main(String[] args) {
        ShoppingListener shoppingListener = new ShoppingListener();
        SleepListener sleepListener = new SleepListener();

        SimpleEventMulticaster simpleEventMulticaster = new SimpleEventMulticaster(new ArrayList<WeekendListener>());
        simpleEventMulticaster.addListener(shoppingListener);
        simpleEventMulticaster.addListener(sleepListener);

        simpleEventMulticaster.multicaster(new ShoppingEvent());

        simpleEventMulticaster.removeListener(shoppingListener);
        simpleEventMulticaster.multicaster(new ShoppingEvent());
    }
}

輸出結果:

start 搞事情
hello, shopping
end 搞事情
start 搞事情
end 搞事情

解釋:這里定義了觀察者WeekendListener,這個觀察者的作用就是觀察周末到底要干啥,然后定義了兩個具體觀察者,就是ShoppingListener和SleepListener,這兩個是具體觀察者,觀察這個人是睡覺還是去購物,然后就定義了兩種行為,也就是兩個事件SleepEvent和ShoppingEvent,這兩個事件就是具體的狀態,然后定義了目標就是AbstractEventtMulticaster,這個里面定義了觀察者的集合,定義了新增和刪除觀察者,同時還定義了一個關鍵的方法multicaster,這個方法會在出現具體的事件的時候,將事件廣播給每一個觀察者,然后執行回調onEvent()方法,其實在具體觀察者中可以定義interest()方法,這個方法的作用就是看這個具體的觀察者是不是對這個事件感興趣,如果感興趣就可以執行具體某個行為。

 

下一篇文章我會結合springboot源碼分析springboot是如何使用觀察者模式的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM