火狐浏览器网站开发人员域名可以免费注册码
2026/3/13 19:12:58 网站建设 项目流程
火狐浏览器网站开发人员,域名可以免费注册码,网页美工设计课程教案,个人网站带论坛 备案概述 有时候#xff0c;我们只是想发布一些本地的事件#xff0c;并不需要引入MQ的#xff0c;可以直接使用Spring的ApplicationEventPublisher来完成简单事件的发布和监听的。 比如像下面的场景#xff0c;ApplicationEventPublisher就够用了。 模块间的逻辑解耦#…概述有时候我们只是想发布一些本地的事件并不需要引入MQ的可以直接使用Spring的ApplicationEventPublisher来完成简单事件的发布和监听的。比如像下面的场景ApplicationEventPublisher就够用了。模块间的逻辑解耦但不跨服务轻量级的本地事件通知应用内部的解耦和扩展点:比如说在DDD里聚合保存数据成功后需要触发若干的后续动作无强事务要求、无强持久化要求的通知场景生产环境实战,门店创建成功后发布【门店已成功创建的事件】在我目前这边门店一旦创建成功后是有很多一系列的后续动作要去做的比如配置门店的各种各样的规则信息。具体的代码很简单。就是用ApplicationEventPublisher的publishEvent方法发布事件用EventListener注解监听事件就可以了。具体的代码实现如下。事件发布者封装 ApplicationEventPublisherShopCreationEventPublisher对 Spring 的ApplicationEventPublisher做了一层封装统一事件创建和日志输出Component RequiredArgsConstructor Slf4j public class ShopCreationEventPublisher { private final ApplicationEventPublisher applicationEventPublisher; public void publishShopCreationEvent(Long shopId) { if (shopId null) { return; } applicationEventPublisher.publishEvent( new ShopCreationEvent( shopId, ShopConstant.ShopDomainEvent.SHOP_CREATION_EVENT.getCode() ) ); log.info(Publishing {} for shopId: {}, ShopConstant.ShopDomainEvent.SHOP_CREATION_EVENT.getCode(), shopId); } }AllArgsConstructor Getter public enum ShopDomainEvent { SHOP_CREATION_EVENT(shop_creation_event, 门店已创建), SHOP_UPDATE_EVENT(shop_update_event, 门店已更新); /** * 编码 */ private final String code; /** * 描述 */ private final String desc; }这个类做了几件小事封装事件构造上层只需要传shopId不关心事件 code 的细节ShopDomainEvent定义门店的时间有创建和更新通过这层封装业务代码几乎完全与ApplicationEventPublisher解耦只依赖一个语义明确的发布器。ShopApplicationService类只需要调用发布方法事件就发布出去了。RequiredArgsConstructor Service Slf4j public class ShopApplicationService { private final ShopCreationEventPublisher shopCreationEventPublisher; /** * 保存门店聚合信息 */ public void saveShopInfo(SaveShopInfoCommand saveShopInfoCommand) { // 构建聚合根 ShopInfoAggregateRoot root shopInfoFactory.createShopInfoAggregateRoot(saveShopInfoCommand); // 持久化 shopInfoRepository.persistence(root); // 发布【门店已创建】的事件 shopCreationEventPublisher.publishShopCreationEvent(root.getId()); } }事件监听者实现用EventListener注解就可以了。Component Slf4j RequiredArgsConstructor class NewShopRuleGenerateListener { EventListener public void onShopCreationEvent(ShopCreationEvent event) { log.info(NewShopRuleGenerateListener received : {}, JSON.toJSONString(event)); Long shopId event.getShopId(); if (shopId null) { return; } // 新启一个线程执行避免阻塞事件发布线程 new Thread(() - { ShopInfoAggregateRoot shopInfoAggregateRoot shopInfoRepository.selectByShopId(shopId.intValue()); // 新增的门店配置各种各样的规则 }).start(); }可以看出监听方式非常直观通过EventListener标注方法参数就是要监听的事件类型ShopCreationEvent业务逻辑完全从ShopApplicationService中拆了出来转移到一个职责清晰的监听器类里为避免阻塞事件发布线程监听器内部主动使用新线程执行耗时操作这条链路的好处在于保存门店的主流程对“谁在监听这个事件”是无感知的新增或删除监听器只影响监听方代码不需要修改ShopApplicationService实战落地建议尽量为每类事件提供单独的发布器比如ShopCreationEventPublisher、ShopUpdatePublisher而不是在业务代码里直接拿ApplicationEventPublisher便于后续在发布器层面统一做日志、限流或埋点事件命名和字段保持业务语义清晰ShopCreationEvent这种名称比“门店变更事件”更具体事件体只放必要字段比如shopId、事件类型 code避免变成“大而全 DTO监听器职责要单一一个监听器专注做一件事情如果后续还有“新门店初始化库存”、“新门店推送消息”等可以新建监听器按职责拆分异步处理尽早抽象到统一机制目前上面的代码使用new Thread。这个是不太合理的 应该是用线程池。在不引入 MQ 的前提下基于 ApplicationEventPublisher 的这种本地事件机制可以在保持代码结构清晰的同时给系统预留足够的扩展点对很多中小体量的业务来说这种方案已经足够实用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询