概述
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事件总线所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复