当使用Spring Data Common时,它可以在聚合根的构造函数中注册域事件吗?



聚合将由某个application service创建,而不是由另一个聚合创建。

喜欢这个

SomeAggregate aggregate = new SomeAggregate();
repo.save(aggregate);

期望在应用程序服务结束时保存aggregate并发布一个SomeAggregateCreated事件。我已经测试过它,它并不总是有效的,有时在执行构造函数后不会立即注册事件。

这是教师课:

public class Teacher extends AbstractAggregateRoot<Teacher> {
public Teacher() {
registerEvent(new TeacherAdded(id, name));
}
}

这是TeacherAdded

@AllArgsConstructor
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
public class TeacherAdded extends AbstractDomainEvent {
private TeacherId teacherId;    
private String name;
}

这是AbstractDomainEventDomainEvent

@Getter
@ToString()
@EqualsAndHashCode()
public abstract class AbstractDomainEvent implements DomainEvent {
protected Date occurredOn;
public AbstractDomainEvent() {
this(new Date());
}
public AbstractDomainEvent(Date occurredOn) {
this.occurredOn = occurredOn != null ? occurredOn : new Date();
}
@Override
public Date occurredOn() {
return occurredOn;
}    
}
public interface DomainEvent {
public Date occurredOn();
}

AbstractAggregateRoot是从org.springframework.data.domain.AbstractAggregateRoot<A>复制的,并添加了hasCapturedEvent方法进行测试。

public boolean hasCapturedEvent(DomainEvent event) {
return domainEvents.contains(event);
}

如果我运行这个:

// ...
TeacherAdded teacherAdded = new TeacherAdded(teacherId, teacherName);
Teacher teacher = new Teacher();
assertTrue(teacher.hasCapturedEvent(teacherAdded)); 

它有时失败,有时成功。

答案是yes.构造函数注册的域事件可以正常发布和监听。它们与通过常规方法注册的事件相同。

我在问题描述中提供的测试有缺陷。修改AbstractDomainEvent.hasCapturedEvent及其关联代码后,测试即可通过。

这是新的AbstractDomainEvent.hasCapturedEvent和测试方法。

public boolean hasCapturedEvent(DomainEvent event, long occurredOnAdjustment) {
if (occurredOnAdjustment <= 0) {
return this.domainEvents.contains(event);
} else {
return this.domainEvents.stream().anyMatch(eventOnStream -> {
return eventOnStream.equalsExcludedOccurTime(event)
&& System.currentTimeMillis() - eventOnStream.occurredOn().getTime() <= occurredOnAdjustment;
});
}
}
TeacherAdded teacherAdded = new TeacherAdded(teacherId, teacherName);
Teacher teacher = new Teacher();
assertTrue(teacher.hasCapturedEvent(teacherAdded, 1000L)); 

这是新的TeacherAdded.

public interface DomainEvent {
public Date occurredOn();
public default boolean equalsExcludedOccurTime(DomainEvent other) {
return false;
}
}
@lombok...
public class TeacherAdded extends AbstractDomainEvent {
private TeacherId teacherId;    
private String name;
@Override
public boolean equalsExcludedOccurTime(DomainEvent other) {
if (!(other instanceof TeacherAdded)) {
return false;
} else {
TeacherAdded other2 = (TeacherAdded)other;
return Objects.equals(teacherId, other2.teacherId)
&& Objects.equals(name, other2.name);
}
}
}

相关内容

  • 没有找到相关文章

最新更新