SpringBoot整合EventBus事件驱动

序言

  在开发中,有时候会使用到发布订阅模式,之前一直以为只要MQ才能实现,后来了解到Spring也可以通过自己的Event事件来实现发布订阅,相比MQ功能会弱很多,但是也会相对简单很多。
  Spring原生的使用方式,有兴趣的小伙伴可以研究一下。实际开发可以使用Guava的EventBus以及org.greenrobot的EventBus,两者名字相同,功能也很相似,我使用的后者greenrobot。
学习过程中踩的坑:

  • 依赖分不清:各种博客都在说guava的EventBus是多么的厉害,但是使用的依赖却不是guava的;
  • 功能讲不清:原谅小白的我确实再翻遍了各种博客后更加懵逼,大部分实现我都是去官网上看了事例才明白的。

1、添加依赖

<dependency>
	<groupId>org.greenrobot</groupId>
	<artifactId>eventbus</artifactId>
	<version>3.2.0</version>
</dependency>
<!-- 有兴趣研究guava的朋友使用下面的依赖(本事例不需要下面的依赖),一个来自Google的强大工具包  -->
<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>22.0</version>
</dependency>

2、文档资料

传送门:eventbus文档

小提示:英文网站,可以使用谷歌浏览器翻译,基本误差不大。

3、使用

3.1 配置EventBus

@Configuration
public class EventConfig {
	// 使用@Bean配置EventBus,以后直接注入使用即可
    @Bean
    public EventBus eventBus() {
        return EventBus.getDefault();
    }
}

3.2 定义事件

// 定义事件,使用普通的POJO即可,这里之所以定义两个pojo,并且字段名一样。
// 就是我之前有个疑问:事件驱动的时候会不会错乱
public class LoginEvent implements Serializable {
    private static final long serialVersionUID = -6787105919337013565L;
    private String telePhone;
    private String email;
    private String goodsName;
}

public class OrderEvent implements Serializable {
    private static final long serialVersionUID = 8794979353646765379L;
    private String telePhone;
    private String email;
    private String goodsName;
}

3.3 准备订阅者

订阅者实现事件处理方法(也称为“订阅者方法”),在事件发布时将被调用。这些通过@Subscribe注释定义。
注意,使用EventBus 3可以自由选择方法名称(没有像EventBus 2那样的命名约定)。

@Component
public class LoginListener {
	// 同步方法
    @Subscribe
    public void orderTel(LoginEvent loginEvent) {
        ThreadUtil.sleep(3000L);
        System.out.println("接收到登录消息++发送短信,telePhone="
                + loginEvent.getTelePhone() + ", goodsName=" + loginEvent.getGoodsName()  
				+ "== " + LocalDateTime.now());
    }

	// 同步方法
	@Subscribe
    public void orderEmail(LoginEvent loginEvent) {
        ThreadUtil.sleep(3000L);
        System.out.println("接收到登录消息++发送邮件,email="
                + loginEvent.getEmail() + ", goodsName=" + loginEvent.getGoodsName()  + 
				"== " + LocalDateTime.now());
    }
}
@Component
public class OrderListener {
	// 异步方法
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void orderTel(OrderEvent orderEvent) {
        ThreadUtil.sleep(3000L);
        System.out.println("接收到订单消息--发送短信,telePhone="
                + orderEvent.getTelePhone() + ", goodsName=" + orderEvent.getGoodsName()  
				+ "== " + LocalDateTime.now());
    }

	// 异步方法
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void orderEmail(OrderEvent orderEvent) {
        ThreadUtil.sleep(3000L);
        System.out.println("接收到订单消息--发送邮件,email="
                + orderEvent.getEmail() + ", goodsName=" + orderEvent.getGoodsName()  + 
				"== " + LocalDateTime.now());
    }
}

3.4 注册或注销总线

用户也需要注册和注销总线。这样消息订阅者才能收到事件。

@Component
public class EventHandler {
    @Autowired
    private EventBus eventBus;

    @Autowired
    private OrderListener orderListener;

    @Autowired
    private LoginListener loginListener;

    /**
     * 注册总线
     */
    @PostConstruct
    public void init() {
        eventBus.register(orderListener);
        eventBus.register(loginListener);
    }

    /**
     * 注销总线
     */
    @PreDestroy
    public void destroy() {
        eventBus.unregister(orderListener);
        eventBus.unregister(loginListener);
    }

    /**
     * 发布活动
     * @param obj 事件
     */
    public void eventPost(Object obj){
        eventBus.post(obj);
        System.out.println("分发消息完成");
        ThreadUtil.sleep(4000L);
    }
}

3.5 发布活动

主要是调用上一步的eventPost方法,现在模拟一个接口来调用:

@RestController
public class EventCotroller {
    @Autowired
    private EventHandler eventHandler;

    @GetMapping("/eventPost")
    public String eventPost() {
        LoginEvent loginEvent = new LoginEvent("22222222", "1111@qq.com", "Java实战1111");
        OrderEvent event = new OrderEvent("13751528565", "742457@qq.com", "Java实战");
        eventHandler.eventPost(loginEvent);
        eventHandler.eventPost(event);
        return "ok";
    }
}

运行结果

接收到登录消息++发送邮件,email=1111@qq.com, goodsName=Java实战1111== 2020-12-20T17:38:54.844
接收到登录消息++发送短信,telePhone=22222222, goodsName=Java实战1111== 2020-12-20T17:38:57.845
分发消息完成
分发消息完成
接收到订单消息–发送邮件,email=742457@qq.com, goodsName=Java实战== 2020-12-20T17:39:00.860
接收到订单消息–发送短信,telePhone=13751528565, goodsName=Java实战== 2020-12-20T17:39:00.860

可以看出使用了异步注解@Subscribe(threadMode = ThreadMode.ASYNC)的Order事件执行更加高效。

4、结尾

更多操作可参考开头的官网,带你领略事件驱动的更多方式。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在Spring Boot中集成EventBus可以通过以下步骤进行: 1. 添加EventBus依赖:在`pom.xml`文件中添加EventBus的依赖,例如: ```xml <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.1-jre</version> </dependency> ``` 2. 创建事件类:创建表示事件的类,例如: ```java public class MyEvent { private String message; public MyEvent(String message) { this.message = message; } public String getMessage() { return message; } } ``` 3. 创建事件监听器:创建事件监听器类,用于处理事件,例如: ```java @Component public class MyEventListener { @Subscribe public void handleEvent(MyEvent event) { // 处理事件逻辑 System.out.println("Received event: " + event.getMessage()); } } ``` 4. 配置EventBus:在Spring Boot的配置类中配置EventBus,例如: ```java @Configuration public class EventBusConfig { @Bean public EventBus eventBus() { return new EventBus(); } @Autowired public void setListeners(EventBus eventBus, MyEventListener listener) { eventBus.register(listener); } } ``` 5. 发布事件:在需要发布事件的地方,注入EventBus并发布事件,例如: ```java @Service public class MyService { @Autowired private EventBus eventBus; public void doSomething() { // 执行业务逻辑 // ... // 发布事件 eventBus.post(new MyEvent("Hello EventBus!")); } } ``` 这样,当`MyService`中的`doSomething`方法被调用时,会触发`MyEvent`事件,并由`MyEventListener`监听器处理该事件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值