问题描述
所以我目前正在使用 Spring boot 和 Axonframework 开发应用程序,所以在 Axonframework 中有一个叫做聚合的东西。它可以存储一些状态等。一切正常,但有一种情况,我必须在更新聚合之前检查每个传入命令的相同状态。像这样
@CommandHandler
fun handle(command: UpdateProductCommand){
if (isProductApproved){
throw IllegalArgumentException("This product has not been approved by qa.")
}
... do something
}
@CommandHandler
fun handle(command: PublishProductCommand){
if (isProductApproved){
throw IllegalArgumentException("This product has not been approved by qa.")
}
... do something
}
... Some other commands
... Check the same state again and again to every command
如您所见,对于大多数命令,我必须检查此 isProductApproved。无论如何,在开始执行某些逻辑之前,是否可以轻松地将此检查状态应用于每个功能或命令。我期待这样的事情
@Aggregate
@CheckState(value = isProductApproved)
class ProductAggregate {
... apply to every command
}
或者任何更好的方法。
解决方法
在 Axon 框架应用程序中,可以为包含处理程序(在您的情况下为聚合)的特定组件定义处理程序拦截器。这可以通过添加处理消息的方法并结合 @MessageHandlerInterceptor
注释来实现。
您可以在官方 Axon Reference guide(文档)中找到更多详细信息:https://docs.axoniq.io/reference-guide/axon-framework/messaging-concepts/message-intercepting#messagehandlerinterceptor
在我看来,这将是执行某些特定组件通用逻辑的最实用方法,在您的情况下,这是一个聚合(但实际上它可以是任何其他消息传递组件:例如事件/查询处理程序)
,您提到您必须将此检查添加到大多数命令,而不是所有命令。如果确实有可能出现规则的例外情况,我认为以下无聊的低技术解决方案可能是最合适的,即使它可能不是您的想法:
private fun requireProductIsApproved() = require(isApprovedProduct) {
"This product has not been approved by qa."
}
@CommandHandler
fun handle(command: PublishProductCommand){
requireProductIsApproved()
//... do something
}
为什么?
- 太简单了
- 它很灵活:只需在不需要检查的 CommandHandlers 中省略它即可。
- 它使您的域逻辑独立于 Axon 特定的机制