AxonFrameworkCommand调度程序
命令处理程序篇提供了有关如何在应用程序中处理命令消息的背景信息。 调度过程是这种命令消息的起点。 Axon 提供了两个接口,可用于将命令发送到命令处理程序,它们是: 命令总线和 命令网关
本篇将显示如何以及何时使用命令网关和总线。 基础设施篇讨论了如何配置命令网关和总线实现的细节。 命令总线
"Command Bus" 是将命令分派给它们各自的命令处理程序的机制。 因此,基础设施组件知道哪个组件可以处理哪个命令。
每个命令总是被发送到一个命令处理程序。 如果分派的命令没有可用的命令处理程序,则会引发 NoHandlerForCommandException 异常。
CommandBus 提供了两种方法将命令分派到它们各自的处理程序,分别是 dispatch(CommandMessage) 和 dispatch(CommandMessage, CommandCallback) 方法:private CommandBus commandBus; // 1. public void dispatchCommands() { String cardId = UUID.randomUUID().toString(); // 2. // 3. & 4. commandBus.dispatch(GenericCommandMessage.asCommandMessage(new IssueCardCommand(cardId, 100, "shopId"))); // 5. & 6. commandBus.dispatch( GenericCommandMessage.asCommandMessage(new IssueCardCommand(cardId, 100, "shopId")), (CommandCallback) (cmdMsg, cmdResultMsg) -> { // 7. if (cmdResultMsg.isExceptional()) { Throwable throwable = cmdResultMsg.exceptionResult(); } else { String commandResult = cmdResultMsg.getPayload(); } } ); } // omitted class, constructor and result usage
上面描述的 CommandDispatcher 举例说明了调度命令的几个重要方面和功能:CommandBus 接口提供发送命令消息的功能。根据最佳实践,聚合标识符被初始化为随机唯一标识符的字符串。
类型化的标识符对象也是可以的,只要该对象实现了一个合理的 toString() 函数。GenericCommandMessage#asCommandMessage(Object) 方法用于创建 CommandMessage 。
为了能够在 CommandBus 上发送命令,您需要将自己的命令对象(例如 "command message payload")包装在 CommandMessage 中。
CommandMessage 还允许将 MetaData 添加到命令消息中。CommandBus#dispatch(CommandMessage) 函数将在总线上分派提供的 CommandMessage ,以传递给命令处理程序。
如果应用程序对命令的结果不直接感兴趣,则可以使用此方法。如果命令处理的结果与您的应用程序相关,则可以提供可选的第二个参数 CommandCallback 。
CommandCallback 允许在命令处理完成时通知调度组件。命令回调有一个函数,onResult(CommandMessage, CommandResultMessage) ,它在命令处理完成时被调用。
第一个参数是调度命令,第二个参数是调度命令的执行结果。
最后,CommandCallback 是一个 "functional interface",因为 onResult 是它的唯一方法。
因此,commandBus.dispatch(commandMessage, (cmdMsg, commandResultMessage) { /* … */ }) 也是可以的。CommandResultMessage 提供 API 来验证命令执行是否异常或成功。
如果 CommandResultMessage#isExceptional 返回 true,您可以假设 CommandResultMessage#exceptionResult 将返回包含实际异常的 Throwable 实例。
否则,CommandResultMessage#getPayload 方法可能会为您提供实际结果或 null ,如此处进一步指定。
命令回调注意事项
在使用 dispatch(CommandMessage, CommandCallback) 的情况下,调用组件可能不会假定回调是在分派命令的同一线程中调用的。 如果调用线程在继续之前依赖于结果,则可以使用 FutureCallback 。 FutureCallback 是 Future (定义在 java.concurrent 包中)和 Axon 的 CommandCallback 的组合。 或者,考虑使用 CommandGateway 。命令网关
"Command Gateway" 是一种用于调度命令的便捷方法。 它通过在 CommandBus 上调度命令时为您抽象某些方面来做到这一点。 它使用下面的 CommandBus 来执行消息的实际调度。
虽然您不需要使用网关来分派命令,但它通常是最简单的选择。
CommandGateway 接口可以分为两组方法,即 send 和 sendAndWait :private CommandGateway commandGateway; // 1. public void sendCommand() { String cardId = UUID.randomUUID().toString(); // 2. // 3. CompletableFuture futureResult = commandGateway.send(new IssueCardCommand(cardId, 100, "shopId")); } // omitted class, constructor and result usage
如上所示的 send API 引入了几个概念,并标有编号的注释:CommandGateway 接口提供发送命令消息的功能。
它通过在内部利用 CommandBus 接口调度消息来实现。根据最佳实践,聚合标识符被初始化为随机唯一标识符的字符串。
类型化的标识符对象也是可以的,只要该对象实现了一个合理的 toString() 函数。send(Object) 函数需要一个参数,即命令对象。
这是一种调度命令的异步方法。
因此 send 方法的响应是 CompletableFuture 。
这允许在返回命令结果后链接后续操作。
使用 send(Object) 时的回调
CommandGateway#send(Object) 方法在后台使用 FutureCallback 来解除命令调度线程与命令处理线程的阻塞。
通过使用 sendAndWait 方法,也可以实现发送消息的同步方法:private CommandGateway commandGateway; public void sendCommandAndWaitOnResult() { IssueCardCommand commandPayload = new IssueCardCommand(UUID.randomUUID().toString(), 100, "shopId"); // 1. String result = commandGateway.sendAndWait(commandPayload); // 2. result = commandGateway.sendAndWait(commandPayload, 1000, TimeUnit.MILLISECONDS); } // omitted class, constructor and result usageCommandGateway#sendAndWait(Object) 函数接受一个参数,即您的命令对象。
它将无限期地等待,直到命令调度和处理过程已经解决。
该方法返回的结果可以是成功的,也可以是异常的,这里会解释。如果不希望无限期地等待,可以在命令对象旁边提供与 "time unit" 配对的 "timeout"。
这样做将确保命令调度线程不会等待超过指定的时间。
如果在使用此方法时命令调度/处理被中断或超时,则命令结果将为 null 。
在所有其他情况下,结果遵循引用的方法。命令调度结果
一般来说,调度命令有两种可能的结果: 命令处理成功,并且 命令处理异常
结果在某种程度上取决于调度过程,但更多地取决于命令处理程序的实现。 因此,如果 @CommandHandler 注解的函数由于某些业务逻辑而引发异常,则该异常将成为调度命令的结果。
命令处理的成功解决故意不应提供任何返回对象。 因此,如果 CommandBus /CommandGateway 提供响应(直接或通过 CommandResultMessage ),那么您应该假设命令处理成功的结果返回 null 。
虽然可以从命令处理程序返回结果,但这应该很少使用。 命令的意图不应该是检索一个值,因为这表明该消息应该被设计为一个查询消息。 例外情况是聚合根的标识符,或聚合根已实例化的实体的标识符。 该框架在聚合的 @CommandHandler 注解构造函数中内置了一个这样的异常。 如果 "命令处理构造函数" 已成功执行,而不是聚合本身,将返回 @AggregateIdentifier 注解字段的值。
我也来聊聊MIUI13的初体验手机K30Pro开发版内测更新到1。22音箱redmi触屏音箱8开发版已升级MIUIHOME平板开发版公测的小米平板5pro先说说MIUI13PHONE1流畅度真的很大的提升!总是
微信收款码还能用最后一个月?别慌一谣言汇总支付宝微信支付收款码将于3月1日起被禁止商用3月1日起,微信支付宝收款码不能用于经营收款收款码禁止商用。2022年3月份马上就到来了,一些新闻报道出了乌龙,以上说法都是错
微信视频号上线付费直播间DoNews1月25日消息(翟继茹)据悉,微信视频号已经上线首个付费直播间,在免费试看3分钟后,需支付90个微信豆才可以继续观看视频。根据苹果iOS充值页的内容显示,用户可以选择7
腾讯视频制片人张萌被移送公安机关,曾制作你是我的荣耀等热播剧记者刘燕秋编辑此前曝出的腾讯视频制片人张萌涉嫌贪腐事件又有新进展。1月25日,腾讯发布腾讯集团反舞弊通报,并对涉及商业贿赂职务侵占等行为的典型案件进行通报。其中,PCG影视内容制作
有偿征稿四川省大数据产业联合会征稿啦大数据人工智能Python机器学习相关爱好者及从业人士速来!征集内容产业政策解读产业动态信息行业技术热点探讨创新产品发布案例分享和分析大数据技术标准解决方案发展趋势展望与应用研究等
2022年,直屏为何再次成为了新机的首选不知道大家2022年的元旦假期过得如何是否有好好休息呢?对于我们三易生活来说,基本上从去年11月底12月至今,其实一直都维持着相当紧张的工作节奏。原因无它,大家有看过我们的相关内容
2021年发布的旗舰手机中,你最推荐的是哪一部?为什么?只说国产第一小米12pro第二一加10pro(今年不给力)第三iqoo9pro第四真我GT2pro按照性价比真我GT2pro第一,接下来看红米K50超大杯宇宙首款大作是否会上2K屏
同样是小屏旗舰,魅族18s满血配置远胜小米12小屏手机在手机行业里是一个比较特别的存在。一方面是因为小屏手机的受众面较小,另一方面是小屏手机大部分都是大屏手机缩减配置后的产品,这让追求旗舰机体验的小屏用户难以找到心仪的手机。比
为什么变焦镜头覆盖了很多的定焦焦段,有的人还要购买定焦镜头?感谢邀请。有这样购买的人,那是他(她)们都是人像摄影师。而定焦镜头就是为了拍摄人像而打造的,如果说,一个人像摄影师,有了某一个变焦镜头,虽然也能拍摄人像,但是变焦镜头的画质自然不如
买iPhone是买128g的好还是买256g的好?如果资金预算充足的情况下,建议你购买256G或者512G版本,听说iPhone12将会在今晚9月9日凌晨发布,如果是5G手机,而且手机拍摄视频逐步的1080P以及4K成为了主流,甚
RedmiK50宇宙来袭RedmiK40系列是2021的一匹黑马。它在618年赢得了销售冠军,半年多来价格几乎没有波动。可以看出这个模型有多香。(主要是12256g版本)虽然K40的价格相对较低,还有使用