Spring事件发布监听器ApplicationListener原理- 观察者模式

发布于:2024-03-09 ⋅ 阅读:(99) ⋅ 点赞:(0)

据说监听器模式也是mq实现的原理, 不过mq我还没来得及深入学习, 先用spring来理解一下吧

Spring事件发布监听器ApplicationListener原理- 观察者模式

什么是观察者模式

大家都听过一个故事叫做烽火戏诸侯
古时候, 总会有人在城墙上守岗, 为的就是观察是否有来兵, 当守卫观察到不远处有来兵, 就会立刻大喊"打仗了, 打仗了", 这个时候,( 同时点起烽火), 那么这个守卫就是观察者, 观察者观察到的打仗这一事件, 会向各方诸侯传播, 大家一起共同对抗敌人
这就是观察者模式

一个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

前面的烽火戏诸侯是我自己想出来的例子, 可能不贴切, 但是观察者本身不是一个很难理解的点, 观察观察, 很容易想明白嘛

本文含有隐藏内容,请 开通VIP 后查看

微信公众号

今日签到

点亮在社区的每一天
去签到