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