聚合将由某个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;
}
这是AbstractDomainEvent
和DomainEvent
@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);
}
}
}