EventBus是Guava实现的的事件处理机制,是设计模式中的发布订/阅模式的优雅和简单的解决方案。通过这种方式,我们既不需要创建复杂的类结构,也没有复杂的接口层次结构,就可以快速实现基于事件模型的发布/订阅模式。
如果对事件监听和发布/订阅模式的实现,只能推荐一种的话,那么首选就是Guava的EventBus。
集成Guava的EventBus非常简单,只需要把自定义的 Event
和 EventListener
放入 EventBus
,然后你就可以通过EventBus来发布消息了。下面一步步讲解一下。
:tractor: 本文源码Github地址
首先为项目增加guava依赖,同时我们引入了Lombok来简化JavaBean的定义。
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.1-jre</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> 复制代码
你可以看到我们自定义的Event不需要实现Guava的任何接口,只要把自己需要用到的事件参数定义好就行了。这里我们只提供一个message参数。
package net.ijiangtao.tech.designpattern.pubsub.guava; import lombok.AllArgsConstructor; import lombok.Data; /** * CustomEvent * * @author ijiangtao * @create 2019-05-02 18:21 **/ @AllArgsConstructor @Data public class CustomEvent { private String message; } 复制代码
通过在方法上添加Guava的 @Subscribe
注解,我们可以让方法监听某个Event。
package net.ijiangtao.tech.designpattern.pubsub.guava; import com.google.common.eventbus.Subscribe; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import java.util.List; /** * EventListener * * @author ijiangtao * @create 2019-05-02 18:15 **/ @Slf4j @Data @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PRIVATE) public class CustomEventListener { private List<String> listenedMessageList; @Subscribe public void onEvent(CustomEvent event) { log.info("Guava EventListener listened one message : {}", event.getMessage()); listenedMessageList.add(event.getMessage()); } } 复制代码
EventBus
的 register
方法可以将前面定义好的监听器注册到 EventBus
中, post
方法可以发布事件并通知到所有订阅该事件的监听器, unregister
方法可以把指定的监听器从 EventBus
中移除。
package net.ijiangtao.tech.designpattern.pubsub.guava; import com.google.common.eventbus.EventBus; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; /** * guava event bus tests * * @author ijiangtao * @create 2019-05-02 18:24 **/ @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class GuavaEventBusTests { @Test public void test() { EventBus eventBus = new EventBus(); List<String> listenedMessageList = new ArrayList<>(); CustomEventListener customEventListener = new CustomEventListener(listenedMessageList); eventBus.register(customEventListener); eventBus.post(new CustomEvent("post a custom event ---- 1")); eventBus.unregister(customEventListener); eventBus.post(new CustomEvent("post a custom event ---- 2")); } } 复制代码
这篇文章,我们快速演示了如何使用Guava的EventBus来实现发布/订阅模式。EventBus作为一种事件机制的轻量、简单、低侵入的实现方式,在简单的事件处理场景下是非常推荐使用的。
如果你的事件处理机制有分布式或者条件过滤等要求,可以考虑使用之前介绍的Redis 发布/订阅模式 或者 Spring Events 事件驱动模型 。