基于Spring的发布订阅模式 EventListener( 三 )

好了 , 通过这3步,我们就可以在spring中愉快的实现事件-监听机制了 。在我们需要发送事件时,只要调用 EventService的发送方法即可
@Slf4j@Builder@Data@AllArgsConstructor@NoArgsConstructorpublic class Order extends BaseDO implements OrderPublisher {private Long orderId;private String bizType;private String tradeOrderNo;private Long totalFee;private Long actualPaidFee;private Long discountFee;private Long refundFee;private Date payTime;private Date refundTime;private Integer status;private Long userId;private String tradeChannel;private String attributes;private Long deliveryFee;private List<SubOrder> subOrders;private List<Promotion> promotions;public void create() {this.publish(new OrderCreateEvent(this, this.tradeOrderNo, this.userId));}public void confirm() {this.publish(new OrderConfirmEvent(this, this.tradeOrderNo, this.userId));}public void paid() {this.publish(new OrderPaidEvent(this, this.tradeOrderNo, this.userId));}public void refund(RefundOrderDTO subOrderId) {this.publish(new OrderRefundEvent(this, this.tradeOrderNo, this.userId,subOrderId));}public void canceled() {this.publish(new OrderCancelEvent(this, this.tradeOrderNo, this.userId));}public void finishPaid() {if (this.status == OrderPayStatusEnum.PAID_DONE.getValue() || this.status == OrderPayStatusEnum.PAID_DONE_SHIPPED.getValue()) {return;}if (this.status != OrderPayStatusEnum.UN_PAID.getValue()) {throw new BusinessException(OrderErrorCode.ORDER_STATUS_IS_ERROR);}this.status = OrderPayStatusEnum.PAID_DONE.getValue();this.payTime = new Date();}public void confirmOrder() {if (this.status == OrderPayStatusEnum.PAID_DONE_SHIPPED.getValue()) {return;}if (this.status == OrderPayStatusEnum.CLOSED.getValue()) {return;}if (this.status != OrderPayStatusEnum.PAID_DONE.getValue()) {throw new BusinessException(OrderErrorCode.ORDER_STATUS_IS_ERROR);}this.status = OrderPayStatusEnum.PAID_DONE_SHIPPED.getValue();subOrders.forEach(subOrder -> {if (subOrder.getStatus() != SubOrderStatusEnum.INIT.getValue()) {throw new BusinessException(OrderErrorCode.ORDER_STATUS_IS_ERROR);}subOrder.setStatus(SubOrderStatusEnum.WAIT.getValue());});}public void cancel() {if (this.status != OrderPayStatusEnum.UN_PAID.getValue()) {return;}if (this.status == OrderPayStatusEnum.PAID_OUTTIME.getValue()) {return;}this.status = OrderPayStatusEnum.PAID_OUTTIME.getValue();}public void complete(Long subOrderId) {subOrders.stream().filter(e -> e.getSubOrderId().equals(subOrderId)).forEach(subOrder -> {subOrder.setStatus(SubOrderStatusEnum.END.getValue());});if (subOrders.stream().allMatch(subOrder ->SubOrderStatusEnum.END.getValue().equals(subOrder.getStatus()) ||SubOrderStatusEnum.TXP_CLOSE.getValue().equals(subOrder.getStatus()))) {this.status = OrderPayStatusEnum.SUCCESS.getValue();}}public void refundOrder(Long refundFee, Date refundDate) {if (this.status == OrderPayStatusEnum.UN_PAID.getValue()) {throw new BusinessException(OrderErrorCode.ORDER_STATUS_IS_ERROR);}if (this.status == OrderPayStatusEnum.CLOSED.getValue()) {throw new BusinessException(RefundErrorCode.ORDER_IS_REFUND);}refundOrder(refundFee, refundDate, null, null);}}
使用@EventListener还支持SPEL表达式
@EventListener(condition = "#jkRecordConfirmEvent.jkRecordConfirmEventDTO.cwConfirmAndReturnFlag")@Async("asyncListenerExecutor")
我们可以看到在监听器中,实现的方法使用了@Async注解 。在spring3提供了@Aync注解来完成异步调用 。我们可以使用这个新特性来完成异步调用 。在实际项目中 , 我们一般也是把这两者结合来使用的,特别是监听事件是一件耗时过程时,这种方式降低了代码的耦合性,非常好用 。【基于Spring的发布订阅模式 EventListener】

推荐阅读