写点什么

下单流程解耦新方案 - 你知道 Spring 事件监听机制吗

  • 2022 年 4 月 17 日
  • 本文字数:1370 字

    阅读完需:约 4 分钟

下单流程解耦新方案-你知道Spring事件监听机制吗

一、Spring 事件监听介绍

Spring 对事件监听是通过事件类型、事件类型监听和事件发布器 3 个部分来完成的


// 1. 自定义订单事件public class OrderEvent extends ApplicationEvent {...}// 2. 定义订单监听器@Componentpublic class OrderListener implements ApplicationListener<OrderEvent> {    @Override    public void onApplicationEvent(OrderEvent event) {    // 生成订单、删除购物车、扣减库存    ...    }}// 3. 通过applicationEventPublisher发布事件@Resourceprivate ApplicationEventPublisher applicationEventPublisher;private void saveOrder(MallUserVO mallUserVO, Long couponUserId, List<ShopCatVO> shopcatVOList, String orderNo) {    // 订单检查    ...    // 生成订单号    String orderNo = NumberUtil.genOrderNo();    // 发布订单事件,在事件监听中处理下单逻辑    applicationEventPublisher.publishEvent(new OrderEvent(orderNo, mallUserVO, couponUserId, shopcatVOList));    // 所有操作成功后,将订单号返回    return orderNo;    ...}
复制代码


上面的代码已经是将订单的保存逻辑从下单接口解耦到订单监听器中了,但是 Spring 使用默认自带的SimpleApplicationEventMulticaster事件监听发布类是同步通知事件监听器的,这里会阻塞下单主线程,影响接口响应时长。

二、使用异步的事件监听发布类

由于默认的SimpleApplicationEventMulticaster类是同步调用,这里可以从 2 个方面入手:

  1. 从事件监听器:将事件监听器的事件触发方法改为异步执行,例如加入将生成订单、删除购物车、扣减库存逻辑放入线程池,或者是在onApplicationEvent放上上加上@Async注解,表示该方法异步执行。

  2. 通过修改默认事件监听发布类的taskExecutor属性,这样可以使用已有的件监听发布类来优化相关逻辑


/** * 系统启动时執行 */@Componentpublic class SpringBeanStartupRunner implements ApplicationRunner {
@Override public void run(ApplicationArguments args) throws Exception { // 设置spring默认的事件监听为异步执行 SimpleApplicationEventMulticaster multicaster = SpringContextUtil.getBean(SimpleApplicationEventMulticaster.class); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( 5, 10, 60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(500), new CustomizableThreadFactory("newbee—event-task"), new ThreadPoolExecutor.CallerRunsPolicy() ); multicaster.setTaskExecutor(threadPoolExecutor); }}
复制代码


在系统启动时反射修改SimpleApplicationEventMulticaster类的taskExecutor属性,从而让SimpleApplicationEventMulticaster类支持异步事件通知

三、事件监听机制的代码思考

通过事件监听机制,我们将下单逻辑拆分成如下步骤:

  1. 订单检查

  2. 生成订单号

  3. 发布订单事件,在事件监听中处理订单保存逻辑

  4. 所有操作成功后,将订单号返回每个步骤都是各自独立不互相影响,后期引入消息队列,对代码的改动也是很少,只需将事件发布和事件监听的代码换成消息队列的消息发送和消息监听即可。


最后贴一下实战项目地址newbeemall

发布于: 刚刚阅读数: 2
用户头像

waynaqua 2020.03.10 加入

java开发工程师

评论

发布
暂无评论
下单流程解耦新方案-你知道Spring事件监听机制吗_事件驱动_越长大越悲伤_InfoQ写作平台