发布订阅模式的最佳实践-guava的EventBus
一:背景
项目中大量有例如发送短信,记录日志的一些业务逻辑,这些业务逻辑,不属于业务逻辑的一部分,不应该耦合到业务逻辑中。
在这种场景下,发布订阅模式就可以解耦这种情况。
在google的guava组件中有一种EventBus的发布订阅模式的组件。我们可以借用这种组件实践发布订阅模式。
二:实现DEMO
我们基于Springboot,和guava实现简单的发布订阅模式。
-
定义一个
IObserver
的接口,所有观察者都需要实现这个接口。 -
实现一个
IObserver
接口,创建两个观察者。@Slf4j @Component("messageListener") public class MessageListener implements IObserver { @Subscribe public void sendSms(String message){ log.info("sms msg is -> {}",message); } @Subscribe public void sendWechat(String message){ log.info("wechat message,message -> {}",message); } }
@Component("logListener") @Slf4j public class RecordLogListener implements IObserver{ @Subscribe public void insertLog(BusiLogDto busiLogDto){ log.info("record history log -> {}",busiLogDto); } }
-
创建一个配置类,把这些上面创建的两个观察者注入到
EventBus
,同时把EventBus
注入到容器中。@Configuration public class EventBusConfiguration { @Bean public EventBus eventBus(List<IObserver> observers) { EventBus eventBus = new EventBus(); if (CollectionUtils.isEmpty(observers)) { return eventBus; } for (IObserver observer : observers) { eventBus.register(observer); } return eventBus; } }
-
创建要给测试类,测试一下。
@Test public void testEventBus(){ eventBus.post("send msg ....."); BusiLogDto busiLogDto = new BusiLogDto(); busiLogDto.setId("123"); busiLogDto.setName("lili"); eventBus.post(busiLogDto); }
执行测试类,我们发现打印日志结果如下:
2021-09-27 21:14:05.656 INFO 121452 --- [ main] c.l.d.p.d.o.guava.MessageListener : sms msg is -> send msg ..... 2021-09-27 21:14:05.657 INFO 121452 --- [ main] c.l.d.p.d.o.guava.MessageListener : wechat message,message -> send msg ..... 2021-09-27 21:14:05.657 INFO 121452 --- [ main] c.l.d.p.d.o.guava.RecordLogListener : record history log -> BusiLogDto(id=123, name=lili)
三:说明
-
实现一个基于EventBus的观察者模式
- 创建一个监听类,对监听消息的处理方法,打上
@Subscribe
,组件会通过参数类型调用监听方法。 - 把监听类注册到
EventBus
的实例。 - 然后在需要调用的地方执行
EventBus
的post
方法,如果参数适配就是执行改方法。
- 创建一个监听类,对监听消息的处理方法,打上
-
如果没有找到合适参数的监听器,
EventBus
就是包装成一个DeadEvent
的事件。我们可以提供一个DeadEvent事件处理这类消息。同样,我们创建一个处理
DeadEvent
消息的监听器。@Component @Slf4j public class DeadEventListener implements IObserver { @Subscribe public void hand(DeadEvent deadEvent){ log.info("dead event message -> {}",deadEvent); } }
执行测试:
eventBus.post(7758258L);
结果如下:
2021-09-27 21:24:14.543 INFO 126820 --- [ main] c.l.d.p.d.o.guava.DeadEventListener : dead event message -> DeadEvent{source=EventBus{default}, event=7758258}