gpt4 book ai didi

java - 如何用spring正确发布DDD领域事件?

转载 作者:行者123 更新时间:2023-11-30 01:45:22 25 4
gpt4 key购买 nike

我正在尝试在我的项目中实现领域驱动设计。这是我的基本Aggregate类:

public abstract class UUIDAggregate {
private final DomainEventPublisher domainEventPublisher;

protected void publish(DomainEvent domainEvent) {
domainEventPublisher.publish(domainEvent);
}
}

假设我们有 UserAccount 聚合:

public class UserAccount extends UUIDAggregate {
private String email;
private String username;
private String password;
private String firstName;
private String lastName;

public void update() {
publish(new DomainEventImpl());
}
}

这是我的DomainEventPublisher:

public interface DomainEventPublisher {
void publish(DomainEvent event);
}

这是DomainEventPublisherImpl:

@Component
public class DomainEventPublisherImpl implements DomainEventPublisher{
@Autowired
private ApplicationEventPublisher publisher;

public void publish(DomainEvent event){
publisher.publishEvent(event);
}
}

现在,这似乎是一个好主意,域与实现分离,但这不起作用。 DomainEventPublisher 无法Autowired,因为 UUIDAggregate 不是 @Component@Bean 。一种解决方案是创建 DomainService 并在那里发布事件,但这似乎会将域泄漏到域服务,如果我这样做,我将陷入贫血模型。另外,我可以做的是将 DomainEventPublisher 作为参数传递给每个聚合,但这似乎也不是一个好主意。

最佳答案

一个想法是为域对象建立一个工厂:

@Component
class UserAccountFactoryImpl implements UserAccountFactory {
@Autowired
private DomainEventPublisher publisher;

@Override
public UserAccount newUserAccount(String email, String username, ...) {
return new UserAccount(email, username, ..., publisher);
}
}

那么您创建域对象的代码是“无发布者的”:

UserAccount userAccount = factory.newUserAccount("john@example.com", ...);

或者您可以稍微更改事件发布的设计:

public abstract class UUIDAggregate {
private final List<DomainEvent> domainEvents = new ArrayList<>();

protected void publish(DomainEvent domainEvent) {
domainEvents.add(domainEvent);
}
public List<DomainEvent> domainEvents() {
return Collections.unmodifiableList(domainEvents);
}
}

@Component
class UserAccountServiceImpl implements UserAccountService {
@Autowired
private DomainEventPublisher publisher;

@Override
public void updateUserAccount(UserAccount userAccount) {
userAccount.update();

userAccount.domainEvents().forEach(publisher::publishEvent);
}
}

这与您的建议不同:服务发布事件,但不创建 - 逻辑保留在域对象中。

此外,您可以更改发布商以最大限度地减少样板代码:

public interface DomainEventPublisher {
void publish(UUIDAggregate aggregate);
}

关于java - 如何用spring正确发布DDD领域事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58242089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com