java - 使用 Spring Boot 和 MongoDB 的领域事件

标签 java spring domain-driven-design

我正在使用 DDDSpring 使用 MongoDB

现在 MongoDB 是一个 DocumentDB 并且不存在模式验证,AggregateRoot 和存储在 MongoDB 中的文档类是两个不同的类,Repository 在读取和写入数据到 database 时在这两个类之间转换内容。

由于Root实体类与存储到DB的类不同,Spring不会触发AggregateRootDomainEvents

  • 在将数据存储到数据库后,有没有一种方法可以从存储库中触发根实体的事件? (可能通过显式调用)

  • 因为 MongoDB 和聚合是 1:1 的组合。那么这是否意味着我们通常不应该创建两个不同的类,一个是 AggregateRoot 另一个是用于在 mongoDB 中存储聚合根的文档类?难道我们不必在我们的聚合顶部添加 @Document 注释,这会泄漏我们领域模型中的基础设施代码吗?

最佳答案

一段时间后我找到了解决方案,从投票中我相信其他人也面临着同样的问题,这是解决方案:

问题:我们可以触发领域事件的显式调用吗?

回答:是的,我们可以。在 SpringBoot我们可以使用/Autowire ApplicationEventPublisher界面然后调用publishEvent(event)方法。

如果您正在为 Db 集合和聚合创建一个单独的类,您需要公开您的 DomainEventsClearingDomainEvents 的方法自 AbstractAggregateRoot<T> 以来的总和这些方法为 protected .下面是在创建时引发事件的示例:

public class MyAggregateRootClass extends AbstractAggregateRoot<MyAggregateRootClass> 
{
    public MyAggregateRootClass(String property1, String property2) {

        // set the fields here
        registerEvent(new MyAggregateRootCreated(someArgs));
    }

    public Collection<Object> getDomainEvents() {
        return super.domainEvents();
    }

    public void clearDomainEvents() {
        super.clearDomainEvents();
    }
}

存储库代码如下所示:

@Repository
@RequiredArgsConstructor // using lombok here, you can create a constructor if you want
public class MyAggregateRepository {

    private final ApplicationEventPublisher eventPublisher;

    private final AggregateMongoRepository repository;

    public void save(MyAggregateRootClass aggToSave) {

        AggregateDao convertedAgg = new AggregateDao(aggToSave);

        repository.save(convertedAgg);

        // raise all the domain events
        for (Object event : aggToSave.getDomainEvents())
            eventPublisher.publishEvent(event);

        // clear them since all events have been raised
        aggToSave.clearDomainEvents();
    }
}

这是否意味着我们通常不应该创建两个不同的类,一个是AggregateRoot另一个用于在 mongoDB 中存储聚合根的文档类?

回答:不,不是那个意思。 DDD的目标将分开 infrastructure来自 Domain并保留 Domain不可知所有基础设施代码。如果两者相同,则影响如下:

  • 拥有@Document在你的 Aggregate Class 上注释会让你改变你的Domain如果您正在切换框架或交换 MongodbSQL .
  • 将来,如果您的数据库架构需要更改,您将不得不同时更改聚合类,或者必须设置适配器类。
  • 因为只有在业务需求发生变化时才应该更改域,而不是因为 infrastructure dependencies , 爬行在 infrastructure annotations进入AggregateRoot这不是最好的方法
那么,什么时候才能真正对聚合和数据库集合使用相同的类呢?

如果您只想保持简单并为两者使用相同的类而不创建单独的类,那么请确保您确定以下内容:

  • 如果您绝对确定您永远不会切换数据库或更改框架。
  • 你有一个简单的域模型,你不需要存储 EntitiesAggregate在一个单独的集合中,你不可能那些 Entities会长成自己的Aggregates

最终取决于。欢迎发表评论,我会尽力回答所有问题,在堆栈上非常活跃。

关于java - 使用 Spring Boot 和 MongoDB 的领域事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61632788/

相关文章:

asp.net-mvc - 域驱动设计新手,请简要说明 'value objects'和 'services'

.net - CQRS,DDD同步报告数据库

java - 线程 "AWT-EventQueue-0"中的 ConcurrentModificationException ?

java - 检测哪个监视器显示窗口

java - Netty ByteBuf 到 byte[] 解码器

java - 将 XML 属性解码为对象值

Spring Security有Ip地址问题

java - 限制用户在 JTextField 中输入时间的最佳方法

java - 无法使用 spring boot 找到 html 页面

.net - 构建您的域对象?