Fork me on GitHub

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是如何使用观察者模式的。

posted @ 2020-06-03 16:34  猿起缘灭  阅读(2783)  评论(0编辑  收藏  举报