Spring 对事件监听是通过事件类型、事件类型监听和事件发布器 3 个部分来完成的
// 1. 自定义订单事件
public class OrderEvent extends ApplicationEvent {
...
}
// 2. 定义订单监听器
@Component
public class OrderListener implements ApplicationListener<OrderEvent> {
@Override
public void onApplicationEvent(OrderEvent event) {
// 生成订单、删除购物车、扣减库存
```
}
}
// 3. 通过 applicationEventPublisher 发布事件
@Resource
private 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 个方面入手:
- 从事件监听器:将事件监听器的事件触发方法改为异步执行,例如加入将生成订单、删除购物车、扣减库存逻辑放入线程池,或者是在
onApplicationEvent
放上上加上@Async
注解,表示该方法异步执行。- 通过修改默认事件监听发布类的
taskExecutor
属性,这样可以使用已有的件监听发布类来优化相关逻辑
/**
* 系统启动时執行
*/
@Component
public 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
类支持异步事件通知
通过事件监听机制,我们将下单逻辑拆分成如下步骤:
- 订单检查
- 生成订单号
- 发布订单事件,在事件监听中处理订单保存逻辑
- 所有操作成功后,将订单号返回 每个步骤都是各自独立不互相影响,后期引入消息队列,对代码的改动也是很少,只需将事件发布和事件监听的代码换成消息队列的消息发送和消息监听即可。
最后贴一下实战项目地址newbeemall
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.