我们都知道使用mq是为了业务的解耦,那么在业务代码中插入一段消息发送代码是不是也增加了代码的耦合呢,当然我们可以使用线程池异步发送消息,但是这样依旧让代码变得臃肿,不利于维护,尤其是存在同类型发送消息的业务。
此时我们可以想一下,引入mq机制是为了解耦,那么发送消息的这段代码是否可以理解为发布订阅的过程,那么我们就把发送消息的这段代码定义为一个事件,由监听器对该类型事件进行监听和统一处理,这样便实现了业务解耦,同时也省去了线程的开销。
接下来我给大家展示Spring事件是如何解耦业务代码并实现统一的事件处理。
@Override
public void modifyLeadsContent(ModifyLeadsContentReq modifyLeadsContentReq) {
// 1.查询订单,保证读主库
LeadsWDO leadsWDO = leadsDomainService.getLeadsForceMaster(modifyLeadsContentReq.getLeadsId(), Lists.newArrayList(LeadsCompositionEnum.LEADS_BODY, LeadsCompositionEnum.LEADS_USER, LeadsCompositionEnum.LEADS_MERCHANT));
// 2.执行修改订单信息校验能力
modifyLeadsValidationAbility.validate(leadsWDO, modifyLeadsContentReq);
// 3.修改订单信息,保证事务
leadsDomainService.modifyLeadsContent(leadsWDO, modifyLeadsContentReq);
// 4.发布领域事件
localEventPublisherSwanProxy.publish(new LeadsContentModifiedEvent(this, modifyLeadsContentReq.getLeadsId(), modifyLeadsContentReq));
}
此处我们发布spring事件,和mq机制类似发布后不管,走自己的代码逻辑。
/**
* 订单信息修改异步发送领域消息
*
* @param leadsContentModifiedEvent 订单信息修改事件
*/
@Order(EventListenerOrderConst.SEND_LEADS_CONTENT_CHANGED_MQ_LISTENER_ON_LEADS_CONTRACT_MODIFIED)
@EventListener
public void onLeadsContentModify(LeadsContentModifiedEvent leadsContentModifiedEvent) {
// 若改约仅状态变更,则不需要处理
SwanRetryInvoker.invokeRetryMethod(
SwanConst.SWAN_RETRY_METHOD_IDEMPOTENT_KEY_SEND_LEADS_DATA_CHANGED_MQ_ON_LEADS_CONSUMER_MODIFY_CONTRACT,
IdempotentValueDecider.decideForEventListener(leadsContentModifiedEvent),
() -> {
leadsOrderContentChangeRemoteProducer.sendMsg(LeadsOrderContentChangeMqDTOAdapter.adapt(leadsContentModifiedEvent));
});
}
此处由监听器监听改单事件,统一异步发送消息,完成业务解耦。
总结一下spring事件的优点如下:
解耦
- 事件驱动:Spring事件监听基于事件驱动模型,允许应用程序组件之间进行低耦合通信。组件只需发布事件,而无需知道哪些监听器在监听这些事件。
- 解耦生产者和消费者:事件发布者(发送消息的部分)不需要知道谁将处理这些消息,或者处理将如何进行。这增加了代码的模块化,并简化了组件间的交互。
异步处理
- 支持异步:Spring事件可以配置为异步执行,这意味着事件的发布者不会被阻塞,等待所有的监听器处理完事件。这可以提高应用程序的性能和响应能力,特别是在处理耗时任务时。
事务边界内的事件处理
- 事务内事件处理:Spring事务事件可以在事务完成后发送,确保事件的处理逻辑仅在事务成功提交后执行。这对于需要在数据库操作成功后才进行的操作特别有用,如发送通知或更新其他系统状态。
维护性和可扩展性
- 提高维护性:由于组件之间的耦合度降低,维护和修改现有功能变得更加容易。添加新的事件监听器或修改现有逻辑不需要改变事件发布者的代码。
- 易于扩展:可以轻松添加新的事件监听器来响应已有事件,无需修改发布事件的代码,这使得系统易于扩展。
一致性和可靠性
- 增强的错误处理:通过事件监听器,可以在一个集中的地方处理错误和异常,从而提高代码的一臀性和可靠性。
- 事务管理:Spring的声明式事务管理可以与事件监听器结合使用,确保事件处理遵循特定的事务策略。
测试
- 便于测试:由于组件之间的耦合度较低,单独测试事件发布者和监听者变得更加容易。可以独立地测试事件的发布和响应逻辑。
总的来说,使用Spring事件监听发送消息提供了一种灵活、解耦和易于维护的方式来处理应用程序内部的通信。这些特性使得它在构建大型、复杂和高度模块化的Spring应用程序时非常有用。