我是靠谱客的博主 迷人书本,最近开发中收集的这篇文章主要介绍spring eventbus事件总线,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

EventBus事件总线详情

一, GreenRobot EventBus

1 simple demo

  • 定义event bus
package com.example.demo.common.config;
import org.greenrobot.eventbus.EventBus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author leiming
* 2021/1/26 10:25
* @description 事件总线配置
*/
@Configuration
public class EventBusConfig {
@Bean
public EventBus eventBus() {
return new EventBus();
}
}
  • 封装事件传递消息
/**
* @author leiming
* 2021/1/26 11:27
* @description 事件消息
*/
@Data
@Builder
public class EventMessage implements Serializable {
private String msg;
}
  • 定义事件监听
package com.example.demo.event;
import lombok.extern.slf4j.Slf4j;
import org.greenrobot.eventbus.Subscribe;
import org.springframework.stereotype.Component;
/**
* @author leiming
* 2021/1/26 10:30
* @description 事件监听器
*/
@Component
@Slf4j
public class EventListener {
@Subscribe
public void onMessage(EventMessage eventMsg) {
log.info("subscribe message :{}", eventMsg.getMsg());
}
}
  • 注册event bus
package com.example.demo.event;
import lombok.extern.slf4j.Slf4j;
import org.greenrobot.eventbus.EventBus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author leiming
* 2021/1/26 10:32
* @description 事件处理
*/
@Component
@Slf4j
public class EventHandler {
@Autowired
private EventBus eventBus;
@Autowired
private EventListener eventListener;
//初始化注册事件subscriber
@PostConstruct
public void init() {
eventBus.register(eventListener);
}
//销毁事件subscriber
@PreDestroy
public void destroy() {
eventBus.unregister(eventListener);
}
//向event bus传递消息
public void eventPost() {
eventBus.post(EventMessage.builder().msg("hello event").build());
log.info("post event msg");
}
}
//如果event bus post的消息类型和subscriber定义接收的消息类型不一致,则subscriber不会接收到消息
  • 调用EventHandler.eventPost()
11:37:55.817INFO
com.example.demo.event.EventListener - subscribe message :hello event
11:37:56.028INFO
com.example.demo.event.EventHandler - post event msg

2 详解

  • @Subscribe

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.POSTING;
    /**
    * If true, delivers the most recent sticky event (posted with
    * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
    */
    boolean sticky() default false;
    /** Subscriber priority to influence the order of event delivery.
    * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
    * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
    * delivery among subscribers with different {@link ThreadMode}s! */
    int priority() default 0;
    }
    

    - ThreadMode.POSTING:subscriber的调用和post处于同一线程,默认选项。避免了线程的切换,开销最小。在该模式下subscriber处理过程需要简单耗时小,避免阻塞post线程。

    - ThreadMode.MAIN:在Android中,如果post线程是主线程(ui线程),subscriber将在同一线程中被调用;否则,subscriber将以非阻塞的方式排队等待调用。如果不是在Android中,行为和上述POSTING一致。

    - ThreadMode.MAIN_ORDERED:和MAIN不同的地方在于,该模式总是排队等待调用。

    - ThreadMode.BACKGROUND:在Android中subscriber将会在后台进程中调用;如果post线程不是main线程,则subscriber直接在post线程中调用;如果post线程是main线程,则subscriber用一个独立的后台进程调用。如果不在Android中则subscriber总是使用后台线程进行调用。

    - ThreadMode.ASYNC:subscriber会在一个独立的线程中异步调用,独立于main线程和post线程。envent bus使用线程池控制线程并发数量。

  • sticky事件

sticky事件:粘性事件,该类型事件在发送后,除了当前注册的subscriber可以监听到消息外,之后注册的subscriber也同样可以接收到先前发送的sticky事件。在一些场景中可以利用该特性实现缓存的动态刷新,历史信息加载等。

EventBus keeps the last sticky event of a certain type in memory.

  • priority

priority定义一个订阅者的优先级,在同一个ThreadMode中,优先级高的会首先接收到事件信息;在不同的ThreadMode中互不影响。

在一个方法上添加注解@Subscribe即可声明为事件的订阅者,@Subscribe注解中的属性sticky设置为true方可接收注册前的sticky事件。

/**
* @author leiming
* 2021/1/27 15:12
* @description 粘性事件监听器
*/
@Component
@Slf4j
public class StickyEventListener {
@Subscribe(sticky = true)
public void listening(EventMessage msg) {
log.info("sticky listener get msg:{}", msg.getMsg());
}
}
@Autowired
private StickyEventListener stickyEventListener;
public void eventPost() {
eventBus.postSticky(EventMessage.builder().msg("sticky event msg").build());
log.info("finish post event msg");
eventBus.register(stickyEventListener);
}
//调用该方法,可见当sticky事件发送后再注册stickyEventListener,仍然可以接收到该粘性事件 
15:41:54.357INFO
com.example.demo.event.EventHandler - finish post event msg
15:41:54.357INFO
com.example.demo.event.StickyEventListener - sticky listener get msg:sticky event msg

– 注意:subscriber方法的参数必须和post的事件信息的类型相同,否则订阅者(subscriber)无法接收事件信息。

  • EventBus定义
//1.使用默认配置的eventBus
EventBus eventBus = EventBus.getDefault();
//2.手动创建
EventBus eventBus = new EventBus();
//3.自定义,more see {org.greenrobot.eventbus.EventBusBuilder}
EventBus eventBus = EventBus.builder()
//当subscriber抛出异常时打印日志,false时不打印
.logSubscriberExceptions(false)
//当没有subscriber时打印日志
.logNoSubscriberMessages(false)
//没有订阅者时是否发送事件
.sendNoSubscriberEvent(false)
.sendSubscriberExceptionEvent(true)
//当订阅者出现异常时,event bus抛出该异常,并终止执行
.throwSubscriberException(false)
.build();
  • 取消event传递

eventBus.cancelEventDelivery(eventMsg):可以在一个subscriber中手动调用该方法,取消一个event的传递,对于同一个event的阻塞序列中的subscriber将不会接收到该event。

二, Guava EventBus

和GreenRobot EventBus类似

最后

以上就是迷人书本为你收集整理的spring eventbus事件总线的全部内容,希望文章能够帮你解决spring eventbus事件总线所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部