美文网首页
SpringBoot 发布ApplicationEventPub

SpringBoot 发布ApplicationEventPub

作者: 会飞的蜗牛F | 来源:发表于2021-01-27 14:22 被阅读0次

SpringBoot 异步事件实现异步(ApplicationEventPublisher、ApplicationEvent)
​ 当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。

实现方法
自定义需要发布的事件类,需要继承ApplicationEvent类或PayloadApplicationEvent<T>(该类也仅仅是对ApplicationEvent的一层封装)
使用@EventListener来监听事件
使用ApplicationEventPublisher来发布自定义事件(@Autowired注入即可)

好处

可以使核心业务与子业务进行解耦,也方便后期的业务的扩展。如新用户注册之后,需要发放优惠券,此时可以在保存用户之后,发布一个新用户的注册成功事件,通过监听该事件来实现发放优惠券的功能。后期新增一个对新用户进行xxx功能,此时可以新写一个监听注册成功事件的监听器,来处理新的业务逻辑,而不需要修改之前的注册逻辑。

注意事项

1、监听器方法中一定要try-catch异常,否则会造成发布事件(有事务的)的方法进行回滚
2、可以使用@Order注解来控制多个监听器的执行顺序,@Order传入的值越小,执行顺序越高
3、对于需要进行s事务监听或不想try-catch runtime异常,可以使用@TransactionalEventListener注解

参考:https://blog.csdn.net/wanping321/article/details/86667216

定时任务关闭未支付的超时订单举例

1、创建事件,继承ApplicationEvent

public class OrderCancelEvent extends ApplicationEvent {
    private List<EbOrder> orderList;

    public OrderCancelEvent(Object source,List<EbOrder> orderList) {
        super(source);
        this.orderList = orderList;
    }

    public List<EbOrder> getOrderList() {
        return orderList;
    }
}

2、发布订单取消事件(定时任务查询未付款的超时订单,进行关闭)

//修改订单为无效订单
//关闭商户后台系统
dslContext.update(EB_ORDER).set(EB_ORDER.STATUS, OrderStatusEnum.INVALID_ORDER.getStatus()).where(EB_ORDER.ID.in(ids)).execute();
        //创建订单取消事件,接收到事件后关闭微信方订单
BaseApplicationContextUtil.getContext().publishEvent(new OrderCancelEvent(this, dslContext.select().from(EB_ORDER).where(EB_ORDER.ID.in(ids)).fetchInto(EbOrder.class)));
        

3、监听事件

@Component
@Slf4j
public class PayCloseOrderEventListener implements ApplicationListener<OrderCancelEvent> {

    @Autowired
    private NewEbIPayMethodService newEbIPayMethodService;

    @Autowired
    private WeixinPayServiceImpl weixinPayService;

    @Override
    @Async
    public void onApplicationEvent(OrderCancelEvent orderCancelEvent) {
        List<EbOrder> orderList = orderCancelEvent.getOrderList();
        if (CollectionUtils.isEmpty(orderList)) {
            return;
        }
        orderList.forEach(order -> {
            Integer payType = order.getPayType();
            EbPayMethod payMethod = newEbIPayMethodService.getPayMethodByIden(order.getIdentification(), payType);
            if (null != payMethod) {
                JSONObject configJson = JSONObject.parseObject(payMethod.getConfig());
                if (2 == payType) {
                    //微信支付
                    Map<String, String> stringStringMap = weixinPayService.closeOrder(payMethod.getPayCode(),payType, order.getOrderSn());
                    String returnCode = stringStringMap.get("return_code");
                    if (WXPayConstants.SUCCESS.equals(returnCode)) {
                        log.info("订单" + order.getOrderSn() + "微信支付订单关闭成功!");
                    } else {
                        log.error("订单" + order.getOrderSn() + "微信支付订单关闭失败!" + stringStringMap.get("return_msg"));
                    }
                } else if (1 == payType) {
                    //todo 支付宝支付
                }
            }
        });

    }
}

4 、BaseApplicationContextUtil 工具类

@Component("context")
public class BaseApplicationContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public BaseApplicationContextUtil() {
    }

    @Override
    public void setApplicationContext(ApplicationContext contex) throws BeansException {
        applicationContext = contex;
    }

    public static ApplicationContext getContext() {
        return applicationContext;
    }

    public static Object getBean(String name) throws BeansException {
        return applicationContext.getBean(name);
    }

demo参考:https://blog.csdn.net/qq_28060549/article/details/81073001

相关文章

网友评论

      本文标题:SpringBoot 发布ApplicationEventPub

      本文链接:https://www.haomeiwen.com/subject/kskzgktx.html