下單流程解耦新方案-你知道Spring事件監(jiān)聽機(jī)制嗎

一、Spring事件監(jiān)聽介紹

Spring對事件監(jiān)聽是通過事件類型、事件類型監(jiān)聽和事件發(fā)布器3個部分來完成的

// 1. 自定義訂單事件
public class OrderEvent extends ApplicationEvent {
...
}
// 2. 定義訂單監(jiān)聽器
@Component
public class OrderListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent event) {
    // 生成訂單、刪除購物車、扣減庫存
    ```
    }
}
// 3. 通過applicationEventPublisher發(fā)布事件
@Resource
private ApplicationEventPublisher applicationEventPublisher;
private void saveOrder(MallUserVO mallUserVO, Long couponUserId, List<ShopCatVO> shopcatVOList, String orderNo) {
    // 訂單檢查
    ```
    // 生成訂單號
    String orderNo = NumberUtil.genOrderNo();
    // 發(fā)布訂單事件,在事件監(jiān)聽中處理下單邏輯
    applicationEventPublisher.publishEvent(new OrderEvent(orderNo, mallUserVO, couponUserId, shopcatVOList));
    // 所有操作成功后,將訂單號返回
    return orderNo;
    ```
}

上面的代碼已經(jīng)是將訂單的保存邏輯從下單接口解耦到訂單監(jiān)聽器中了,但是Spring使用默認(rèn)自帶的SimpleApplicationEventMulticaster事件監(jiān)聽發(fā)布類是同步通知事件監(jiān)聽器的,這里會阻塞下單主線程,影響接口響應(yīng)時長。

二、使用異步的事件監(jiān)聽發(fā)布類

由于默認(rèn)的SimpleApplicationEventMulticaster類是同步調(diào)用,這里可以從2個方面入手:

  1. 從事件監(jiān)聽器:將事件監(jiān)聽器的事件觸發(fā)方法改為異步執(zhí)行,例如加入將生成訂單、刪除購物車、扣減庫存邏輯放入線程池,或者是在onApplicationEvent放上上加上@Async注解,表示該方法異步執(zhí)行。
  2. 通過修改默認(rèn)事件監(jiān)聽發(fā)布類的taskExecutor屬性,這樣可以使用已有的件監(jiān)聽發(fā)布類來優(yōu)化相關(guān)邏輯
/**
 * 系統(tǒng)啟動時執(zhí)行
 */
@Component
public class SpringBeanStartupRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 設(shè)置spring默認(rèn)的事件監(jiān)聽為異步執(zhí)行
        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);
    }
}

在系統(tǒng)啟動時反射修改SimpleApplicationEventMulticaster類的taskExecutor屬性,從而讓SimpleApplicationEventMulticaster類支持異步事件通知

三、事件監(jiān)聽機(jī)制的代碼思考

通過事件監(jiān)聽機(jī)制,我們將下單邏輯拆分成如下步驟:

  1. 訂單檢查
  2. 生成訂單號
  3. 發(fā)布訂單事件,在事件監(jiān)聽中處理訂單保存邏輯
  4. 所有操作成功后,將訂單號返回
    每個步驟都是各自獨立不互相影響,后期引入消息隊列,對代碼的改動也是很少,只需將事件發(fā)布和事件監(jiān)聽的代碼換成消息隊列的消息發(fā)送和消息監(jiān)聽即可。

最后貼一下實戰(zhàn)項目地址newbeemall

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容