来个开头
EventBus是guava包中的一个事件通知组件,可以用来在同一个JVM中,实现事件通知机制。异步和同步都有实现。这里和Android的EventBus不是一个事物。
在一些业务场景中,我们会使用Redis队列或者Kafka等其他MQ来实现分布式多机器的消息通知,而EventBus是在单个JVM中使用。可以对代码逻辑进行相应的解耦,某些场景下,比如异步调用,可以提高整体的运行性能。
结构和定义
EventBus包含两个大的模块。第一个是发布器,第二个是订阅器。
发布器主要是两个方法:
1、eventBus.register(Object o)
用来注册监听器,传入监听器类型。细节是将监听器有@Subscribe
注解的方法和事件类型对应到一个map里。记得之前有一个eventBus注册多种消息类型的使用方式,这块没有详细了解。
2、eventBus.post(Object o)
顾名思义就是将消息事件发送出去,最后交给有@Subscribe
注解的方法去处理。多个方法可以同时处理一个消息,可以理解为多播。这在多种关联处理的场景中非常有用。
订阅器就比较简单,只有一个@Subscribe
的注解。在收到对应的消息类型之后就可以执行方法中的逻辑。
以下代码是一个简单的应用例子,基于在SpringBoot上构建。
创建一个bean,包括线程池和有界线程队列。这里只是处理消息的线程池,和任务没有直接关系。
//create a new EventBus bean
@Configuration
public class ConfigBean {
@Bean
public EventBus eventBus(){
BlockingQueue<Runnable> queue = new LinkedBlockingDeque<>(100);
ThreadPoolExecutor executor = new ThreadPoolExecutor(2,5,5, TimeUnit.SECONDS,queue);
return new AsyncEventBus(executor);
}
}
在service中创建监听器,注册,发布,接收都写一起了。
@Resource
private EventBus eventBus;
@PostConstruct
public void init() {
eventBus.register(this);
}
public void eventPost(){
String[] strings = new String[]{"A","B"};
eventBus.post(new LogEvent(strings[ThreadLocalRandom.current().nextInt(2)]));
}
@Subscribe
public void eventA(LogEvent event){
log.info("[event-a]=====" + event);
}
@Subscribe
public void eventB(LogEvent event){
log.info("[event-b]=====" + event);
}
@Data
@AllArgsConstructor
private class LogEvent{
private String name;
}
最后在Controller中加个方法,用于手动触发,做简单验证。
@GetMapping("/event")
public String event() {
demoService.eventPost();
return "OK";
}
执行的最终结果日志:
2019-12-16 21:15:39.394 INFO 87204 --- [pool-1-thread-1] c.x.browser.alchemy.service.DemoService : [event-a]=====DemoService.LogEvent(name=A)
2019-12-16 21:15:39.395 INFO 87204 --- [pool-1-thread-2] c.x.browser.alchemy.service.DemoService : [event-b]=====DemoService.LogEvent(name=A)
2019-12-16 21:15:44.599 INFO 87204 --- [pool-1-thread-1] c.x.browser.alchemy.service.DemoService : [event-a]=====DemoService.LogEvent(name=A)
2019-12-16 21:15:44.601 INFO 87204 --- [pool-1-thread-1] c.x.browser.alchemy.service.DemoService : [event-b]=====DemoService.LogEvent(name=A)
2019-12-16 21:20:51.660 INFO 87204 --- [pool-1-thread-2] c.x.browser.alchemy.service.DemoService : [event-a]=====DemoService.LogEvent(name=B)
2019-12-16 21:20:51.660 INFO 87204 --- [pool-1-thread-1] c.x.browser.alchemy.service.DemoService : [event-b]=====DemoService.LogEvent(name=B)
网友评论