美文网首页
Spring广播与监听

Spring广播与监听

作者: 枫林晚_ | 来源:发表于2021-02-23 11:34 被阅读0次

广播服务的顶层接口ApplicationEventPublisher

@FunctionalInterface

public interface ApplicationEventPublisher {

    default void publishEvent(ApplicationEvent event) {

        this.publishEvent((Object)event);

    }

    void publishEvent(Object var1);

}

发送消息就是通过publishEvent方法进行发送,具体的实现在AbstractApplicationContext中,

@Override

public void publishEvent(Object event) {

    publishEvent(event,null);

}

protected void publishEvent(Object event,@Nullable ResolvableType eventType) {

    Assert.notNull(event,"Event must not be null");

    // Decorate event as an ApplicationEvent if necessary

     ApplicationEvent applicationEvent;

    if (event instanceof ApplicationEvent) {

        applicationEvent = (ApplicationEvent) event;

    }

    else {

        applicationEvent =new PayloadApplicationEvent<>(this, event);

        if (eventType ==null) {

            eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();

        }

    }

    //此处判断不成立,初始化过程中的registerListeners方法就会把成员变量earlyApplicationEvents设置为空

     if (this.earlyApplicationEvents !=null) {

        this.earlyApplicationEvents.add(applicationEvent);

    }

    else {

        getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);

    }

    // Publish event via parent context as well...

      if (this.parent !=null) {

        if (this.parent instanceof AbstractApplicationContext) {

            ((AbstractApplicationContext)this.parent).publishEvent(event, eventType);

        }

        else {

            this.parent.publishEvent(event);

        }

    }

}

可以看到广播是通过getApplicationEventMulticaster()方法得到的applicationEventMulticaster这个成员变量来进行的,他是一个ApplicationEventMulticaster接口,最终的multicastEvent调用的是SimpleApplicationEventMulticaster这个实例里的multicastEvent方法,

@Override

public void multicastEvent(final ApplicationEvent event,@Nullable ResolvableType eventType) {

    ResolvableType type = (eventType !=null ? eventType : resolveDefaultEventType(event));

    Executor executor = getTaskExecutor();

    for (ApplicationListener listener : getApplicationListeners(event, type)) {

        if (executor !=null) {

            executor.execute(() -> invokeListener(listener,event));

        }

        else {

            invokeListener(listener, event);

        }

    }

}

再点进invokeListener看看,

发现最终执行的是ApplicationListener接口的onApplicationEvent方法

自定义广播和监听

现在我们知道了Spring的广播和监听的流程,可以自定义自己的广播和监听器了,首先编写一个自定义事件,

自定义事件

然后自定义自己的广播器,将Spring初始化过程中生成的广播器注入进来,

自定义广播

接着自定义自己的监听器,

自定义监听器

最后写一个controller模拟触发,

controller

启动容器,浏览器输入http://localhost:8080/publish,查看打印结果,

结果

至此,Spring的广播和监听基本就结束了,但是,我们可能会有一个小疑问,Spring的事件和监听器是如何绑定的呢?

答案其实是在我们上面看到的广播事件multicastEvent里,

广播事件

这里,他根据事件和事件类型去获取所有的监听器,点进去看看,

获取监听器 绑定事件和监听器的成员变量

可以发现,Spring是将事件和监听器通过一个并发集合来保存的,将事件类型和来源包装成了一个内部类作为key,监听器集合包装成另一个内部类作为value,在Spring容器初始化的时候会把所有的对应关系都注入到这个集合中

相关文章

  • Spring广播与监听

    广播服务的顶层接口ApplicationEventPublisher @FunctionalInterfacepu...

  • BroadCast

    网络状态监听 开机广播监听 发送广播 发送标准广播

  • SpringBoot源码分析之监听器

    1. spring监听器的设计 主要是基于发布订阅者设计模式,由广播器(MultiCaster)、事件(Event...

  • BroadcastReceiver学习笔记

    BroadcastReceiver本质是一种全局监听器,它可以监听全局的广播消息。 与Activity和Servi...

  • 2018年Android的保活方案效果统计

    一、常见保活方案 1、监听广播:监听全局的静态广播,比如时间更新的广播、开机广播、解锁屏、网络状态、解锁加锁亮屏暗...

  • Spring 监听器listener原理-基本使用(一)

    Spring 监听器listener原理-基本使用(一) Spring 监听器listener原理-手写监听器(二...

  • tf

    广播 监听 launch file

  • Home的好基友啊哈哈

    Home按键手势监听 home 按键监听需要打开广播进行监听,同时需要使用动态注册。 分别进行广播的注册和注销,在...

  • android网络监听学习笔记

    网络变化android自带广播、采用广播接收器接收网络变化的监听 自定义广播接收 为了方便全局监听在baseact...

  • Android 锁屏&解锁&开屏监听

    必须动态注册才可以监听到 必须动态注册才可以监听到 必须动态注册才可以监听到 锁屏广播Action 解锁广播Act...

网友评论

      本文标题:Spring广播与监听

      本文链接:https://www.haomeiwen.com/subject/bdkrfltx.html