我遇到了一个触发事件的问题,我认为这是不应该的。 我正在与轴突一起玩,并且正在基于发信事件对发信服务进行建模。我的例子很简单。
我设计了两个输入命令ScheduleLetterCommand
,它们将在几分钟内“发送一个字母” ...如果在该时间段内发送另一个命令CancelLetterCommand
,则用户可以取消它。
我正在通过REST API控制器触发命令...
如果我要安排一封信件并在接下来的五分钟之内立即将其取消,我期望看到的日志语句说一封信件已被安排并取消。
我很好奇地看到这封信已成功安排,并且看到以下日志语句:
Received schedule command for letter id e6e037be-3b6d-4ae3-80cd-12426adcd526
LetterScheduledEvent e6e037be-3b6d-4ae3-80cd-12426adcd526 SCHEDULED
但是当我取消字母时,会看到以下行为:
LetterScheduledEvent e6e037be-3b6d-4ae3-80cd-12426adcd526 SCHEDULED
Received cancel command for letter id e6e037be-3b6d-4ae3-80cd-12426adcd526
Letter e6e037be-3b6d-4ae3-80cd-12426adcd526 cancelled CANCELLED
我在这里想念什么?为什么再次LetterScheduledEvent
处理程序被触发?
这是我的总计-
public class Letter {
@AggregateIdentifier
private String letterId;
private ScheduleToken scheduleToken;
@SuppressWarnings("UnusedDeclaration")
protected Letter() {
// Default constructor required by Axon Framework
}
@CommandHandler
public Letter(ScheduleLetterCommand cmd, EventScheduler scheduler) {
String id = cmd.getLetterId();
log.info("Received schedule command for letter id {}", letterId);
AggregateLifecycle.apply(new LetterScheduledEvent(id, LetterEventType.SCHEDULED));
this.scheduleToken = scheduler.schedule(Duration.ofMinutes(5), new BeginSendLetterEvent(id,LetterEventType.BEGIN_SEND));
}
@CommandHandler
public void handle(CancelLetterCommand cmd, EventScheduler eventScheduler) {
String letterId = cmd.getLetterId();
log.info("Received cancel command for letter id {}", letterId);
AggregateLifecycle.apply(new LetterCancelledEvent(letterId, LetterEventType.CANCELLED));
eventScheduler.cancelSchedule(scheduleToken);
}
@EventSourcingHandler
public void on(LetterScheduledEvent event) {
log.info("LetterScheduledEvent {} {}", event.getLetterId(), event.getEventType());
this.letterId = event.getLetterId();
}
@EventSourcingHandler
public void on(LetterCancelledEvent event) {
log.info("Letter {} cancelled {}", event.getLetterId(), event.getEventType());
scheduleToken = null;
}
@EventSourcingHandler
public void on(BeginSendLetterEvent event) {
log.info("Letter sending process started {} {}", event.getLetterId(), event.getEventType());
//complicated letter sending processes...
AggregateLifecycle.apply(new LetterSentEvent(event.getLetterId(), LetterEventType.SENT));
}
@EventSourcingHandler
public void on(LetterSentEvent event) {
log.info("Letter sent {} {}", event.getLetterId(), event.getEventType());
}
}
这是我的活动->
abstract class LetterMovementEvent(open val letterId: String, open val eventType: LetterEventType)
enum class LetterEventType {
SCHEDULED,
CANCELLED,
BEGIN_SEND,
SENT
}
data class LetterScheduledEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.SCHEDULED
) : LetterMovementEvent(letterId, eventType)
data class LetterCancelledEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.CANCELLED
) : LetterMovementEvent(letterId, eventType)
data class BeginSendLetterEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.BEGIN_SEND
) : LetterMovementEvent(letterId, eventType)
data class LetterSentEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.SENT
) : LetterMovementEvent(letterId, eventType)
答案 0 :(得分:3)
@GoldFish是您要注意的框架,它根据发布的事件来采购您的聚合。 因此,简而言之,您会看到“活动中的事件源”。
使用@EventSourcingHandler
聚合中的Letter
批注,您已经有效地创建了用于基于事件重新创建聚合的方法。
因此,如果您发送命令取消此汇总的字母,它将首先根据事件重新创建汇总。仅在解决此问题后,该命令才实际分配给带有注释的@CommandHandler
方法。
希望这可以为您@GoldFish澄清一下!