SpringBoot整合EventBus事件驱动

序言

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

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

1、添加依赖


	org.greenrobot
	eventbus
	3.2.0



	com.google.guava
	guava
	22.0

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", "[email protected]", "Java实战1111");
        OrderEvent event = new OrderEvent("13751528565", "[email protected]", "Java实战");
        eventHandler.eventPost(loginEvent);
        eventHandler.eventPost(event);
        return "ok";
    }
}

运行结果

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

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

4、结尾

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

你可能感兴趣的:(Spring,java,event)