1. EventBus 介绍

1.1 是什么?

EventBus 是 Guava 的事件处理机制,是观察者模式(生产/消费模型)的一种实现。
观察者模式在我们日常开发中使用非常广泛,例如在订单系统中,订单状态或者物流信息的变更会向用户发送APP推送、短信、通知卖家、买家等等;审批系统中,审批单的流程流转会通知发起审批用户、审批的领导等等。
Observer模式也是 JDK 中自带就支持的,其在 1.0 版本就已经存在 Observer,不过随着 Java 版本的飞速升级,其使用方式一直没有变化,许多程序库提供了更加简单的实现,例如 Guava EventBus、RxJava、EventBus 等
**

1.2 EventBus 优点

相比 Observer 编程简单方便
通过自定义参数可实现同步、异步操作以及异常处理
单进程使用,无网络影响

1.3 缺点

只能单进程使用
项目异常重启或者退出不保证消息持久化
如果需要分布式使用还是需要使用消息中间件

2.使用

2.1 依赖

  1. <dependency>
  2. <groupId>com.google.guava</groupId>
  3. <artifactId>guava</artifactId>
  4. <version>31.0.1-jre</version>
  5. </dependency>

2.2 demos

2.2.1 编写监听类

  1. import com.google.common.eventbus.Subscribe;
  2. import com.shebao.dispatch.businesspeople.dto.event.BusinessPeopleEvent;
  3. import com.shebao.dispatch.domain.businesspeople.gateway.BusinessPeopleGateway;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.stereotype.Component;
  6. import javax.annotation.Resource;
  7. @Component
  8. @Slf4j
  9. public class BusinessPeopleEventListener {
  10. @Resource
  11. private BusinessPeopleGateway businessPeopleGateway;
  12. /**
  13. * 监听
  14. */
  15. @Subscribe
  16. public void listenBusinessPeopleEvent1(BusinessPeopleEvent businessPeopleEvent) {
  17. log.info("收到消息:listenBusinessPeopleEvent-1 -> {}", businessPeopleEvent);
  18. }
  19. /**
  20. * 监听
  21. */
  22. @Subscribe
  23. public void listenBusinessPeopleEvent2(BusinessPeopleEvent businessPeopleEvent) {
  24. log.info("收到消息:listenBusinessPeopleEvent-2 -> {}", businessPeopleEvent);
  25. }
  26. }

2.2.2 配置并注册EventBus

import com.google.common.eventbus.EventBus;
import com.shebao.dispatch.businesspeople.consumer.listener.BusinessPeopleEventListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.concurrent.Executor;


@Configuration
@Slf4j
public class EventBusConfig {

    @Resource
    private BusinessPeopleEventListener businessPeopleEventListener;

    @Resource
    private Executor eventBusAsync;

    /**
     * 同步的
     * @return
     */
    @Bean
    public EventBus businessPeopleEventBus() {
        //异步
        //EventBus eventBus = new AsyncEventBus(eventBusAsync);
        //同步直接new
        EventBus eventBus = new EventBus();
        eventBus.register(businessPeopleEventListener);
        return eventBus;
    }
}

2.2.3 测试类

import com.google.common.eventbus.EventBus;
import com.shebao.dispatch.app.WsApplication;
import com.shebao.dispatch.businesspeople.dto.event.BusinessPeopleEvent;
import com.shebao.dispatch.businesspeople.dto.event.BusinessPeopleEvent.BeforeObject;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

/**
 * 业务人EventBus测试类
 * 前置配置:
 * 1 准备 BusinessPeopleEventListener ,在监听的方法上加注解 @Subscribe
 * 2 com.shebao.dispatch.config.EventBusConfig 中配置一个 businessPeopleEventBus ,并将BusinessPeopleEventListener注册进去
 *
 * 测试: listenBusinessPeopleEvent
 * 使用 businessPeopleEventBus的post方法 发送一个BusinessPeopleEvent类型的对象
 *
 * 结果: BusinessPeopleEventListener的listenBusinessPeopleEvent收到了刚刚发送的对象
 *
 * 注意:EventBus是通过类型来匹配的
 *
 */
@SpringBootTest(classes = {WsApplication.class})
@RunWith(SpringRunner.class)
class BusinessPeopleEventListenerTest {

    @Resource
    private EventBus businessPeopleEventBus;


    @Test
    void listenBusinessPeopleEvent() {
        BusinessPeopleEvent businessPeopleEvent = new BusinessPeopleEvent();
        businessPeopleEvent.setCustomerCode(0L);
        businessPeopleEvent.setCustomerName("");
        businessPeopleEvent.setBusinessType(0);
        businessPeopleEvent.setBusinessPeopleId(0L);
        businessPeopleEvent.setName("");
        businessPeopleEvent.setCertType(0);
        businessPeopleEvent.setCertNo("");
        businessPeopleEvent.setPersonCode("");
        businessPeopleEvent.setPhone("");
        businessPeopleEvent.setCompanyUserId(0L);
        businessPeopleEvent.setWorkingStatus(0);
        businessPeopleEvent.setMsgFlag(0);
        businessPeopleEvent.setBefore(new BeforeObject());
        businessPeopleEventBus.post(businessPeopleEvent);
    }
}

3.提供API

public void register(Object object); // 注册

public void unregister(Object object); //取消注册

public void post(Object event); //发送消息