spring boot plugin_Spring事件监听机制

  • 发短信案例问题分析
  • 利用Spring事件机制完成需求
  • Spring发布异步事件

发短信案例问题分析

假设现在有这么一个业务场景:

用户在京西商城下单成功后,平台要发送短信通知用户下单成功

我们最直观的想法是直接在order()方法中添加发送短信的业务代码:

public 

咋一看没什么不妥,但是如果我们加上一根时间轴,那么代码就有问题了:

一个月后,京西搞了自建物流体系,用户下单成功后,需要通知物流系统发货

于是你又要打开OrderService修改order()方法:

public 

嗯,完美。

又过了一个月,东哥被抓了,股价暴跌,决定卖掉自己的车队,所以下单后就不用通知车队了

重新修改OrderService:

public 

又过了一个月,东哥明尼苏达州荣耀归来:回来做我的兄弟一起开车吧。

好的,东哥。

public 

车队回来了,你却受不了这大起大落异常刺激的生活,决定离职。

就在这时候,组长拉住了你,语重心长地和你说:

小伙子,知道什么叫“以增量的方式应对变化的需求”吗?听过Spring监听机制吗?

说时迟那时快,组长拿来一支笔和一张纸,唰唰唰画了一张图:

ffe0a0ae956dc186d23f9ad742333ef3.png

你顿时心领神会,扑通一声跪在了地上,开始敲起了代码。


利用Spring事件机制完成需求

环境准备

<?xml version="1.0" encoding="UTF-8"?>

OrderService

/**

OrderSuccessEvent(继承ApplicationEvent,自定义事件)

public 

SmsService(实现ApplicationListener,监听OrderSuccessEvent)

/**

Test

@RunWith

输出:

下单成功...
发送短信...
main线程结束...

如果后期针对下单成功有新的操作,可以新写一个事件监听类:

/**

这就是“以增量的方式应对变化的需求”,而不是去修改已有的代码。假设有B接口调用了C接口,你修改了C接口,那么B接口可能业务结果就错了,此时调用B接口的A接口也可能受到影响,是连锁反应。所以,一般我们都提倡“对扩展开放,对修改关闭”的原则。

上面SmsService既是一个服务,还是一个Listener,因为它既有@Service又实现了ApplicationListener接口。

但是仅仅是为了一个监听回调方法而实现一个接口,未免麻烦,所以Spring提供了注解的方式:

/**

Spring发布异步事件

看似很完美了,但是你注意到Spring默认的事件机制是同步的:

b93846f6915834a5be2ea6365db9087a.png

如果针对OrderService下单成功的操作越来越多,比如下单后需要完成的对应操作有十几个,那么等十几个其他服务都调用完毕,东哥可能又去明尼苏达州了。

754e371596fdcbc6a21cc0ec8b94e356.png

所以,你必须想办法把Spring的事件机制改成异步的,尽可能快地返回下单的结果本身,而不是等其他附属服务全部完成(涉及到其他问题暂时按下不表)。

要想把Spring事件机制改造成异步通知,最粗暴的方法是:

OrderService

/**

SmsService

/**

输出:

下单成功...
main线程结束...
发送短信...

c834d4a504f14712569d8bd00018f5f3.png

当然,这种做法其实违背了Spring事件机制的设计初衷。人家会想不到你要搞异步通知?

8ac178c7ac6414a4c38baa89395aaf22.png

当SimpleApplicationEventMulticaster中的Executor不为null,就会执行异步通知。

@Configuration

不好意思,谅解下,肚子饿了,不想解释细节了。

想知道原理的,看另一篇文章:《自定义Spring事件监听机制》

当然了,最后还是要说一句,项目并发高了以后,也不可能用Spring监听机制的,MQ会更合适些。

2020-01-05 17:28:14

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值