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类似

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值