据说监听器模式也是mq实现的原理, 不过mq我还没来得及深入学习, 先用spring来理解一下吧
Spring事件发布监听器ApplicationListener原理- 观察者模式
- 什么是观察者模式
- 一个Demo深入认识一下观察者模式
- Spring中的事件发布监听
- ps
什么是观察者模式
大家都听过一个故事叫做烽火戏诸侯
古时候, 总会有人在城墙上守岗, 为的就是观察是否有来兵, 当守卫观察到不远处有来兵, 就会立刻大喊"打仗了, 打仗了", 这个时候,( 同时点起烽火), 那么这个守卫就是观察者, 观察者观察到的打仗这一事件, 会向各方诸侯传播, 大家一起共同对抗敌人
这就是观察者模式
一个Demo深入认识一下观察者模式
一个观察者
/**
* 观察者 观察温度, 湿度 , 气压
*/
public interface Observer {
void update(float temp, float humidity, float pressure);
}
一个"诸侯"- 当前的气候条件
诸侯其实和观察者是同样的, 在战斗来临时, 都要参与打仗这一事件
/**
* @author Green写代码
* @date 2024-03-05 18:45
* 展示当前的温度适度气压
*/
public class CurrentConditionsDisplay implements Observer {
/**
* 注册一个观察者
* @param weatherData
*/
public CurrentConditionsDisplay(Subject weatherData) {
weatherData.resisterObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
System.out.println("当前的温度, 湿度, 气压为: " + temp + " " + humidity + " " + pressure);
}
}
另一个"诸侯" - 统计的气候
/**
* @author Green写代码
* @date 2024-03-05 18:45
* 统计显示
*/
public class StatisticsDisplay implements Observer {
public StatisticsDisplay(Subject weatherData) {
weatherData.resisterObserver(this);
}
@Override
public void update(float temp, float humidity, float pressure) {
System.out.println("统计显示当前温度湿度气压: " + temp + " " + humidity + " " + pressure);
}
}
气温的类
import java.util.ArrayList;
import java.util.List;
/**
* @author Green写代码
* @date 2024-03-05 18:45
*/
public class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
notifyObserver();
}
@Override
public void resisterObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObserver() {
for (Observer o : observers) {
o.update(temperature, humidity, pressure);
}
}
}
开始执行
public class ObserverTest {
public static void main1(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
weatherData.setMeasurements(0, 0, 0);
weatherData.setMeasurements(1, 1, 1);
}
}
当设置一个气候的时候setMeasurements, 当前温度和统计温度都要随之变化, 因为他们都继承了观察者, 在温度变化的时候, 要共同update温度
Spring中的事件发布监听
发布一个事件
监听
发布和监听是怎么联系起来的呢
我们来看看publishEvent底层
- 首先会将事件转化为ApplicationContext对象, 暂时不是我们所谈论的重点
之后会判断是都是一个earlyApplicationEvents , 英译过来是一个早的事件, 什么叫早的事件?大致就是Spring容器启动的时候, 内部做的一些事件监听, 这个和我们所研究的也不匹配
然后就会走到多播器, 将我们的事件广播出去, 那么监听器就有机会监听到了
让我们继续看这个多播器做了些啥
追踪到这里我们发现, 这不是监听器内部的onApplicationEvent吗
到这里监听器完全监听到了事件, 可以执行监听到的事件了
ps
前面的烽火戏诸侯是我自己想出来的例子, 可能不贴切, 但是观察者本身不是一个很难理解的点, 观察观察, 很容易想明白嘛