7

我正在寻找 Udi Dahan 的域事件模式和基础设施的简单 Java 实现,如本文所述

这很简单,我已经实现了自己的解释,但是我是 Java 新手,不想因为缺乏语言经验而被任何错误所困扰。

我发现的唯一 Java 实现是在Jdon Framework中,但对于我目前的项目来说,它有点过于重量级了。

谢谢!

4

2 回答 2

5

一段时间以来,我一直在寻找 Java EE 中相同问题的解决方案。我查看了Axonjdon(该页面也不是很好的预兆 :))。两者都涉及事件采购,我无法将其“出售”给我的雇主/客户。不过,我想拥有领域事件,因为我在 .NET/C# 项目中非常习惯它们。所以我想出了以下...

我使用了一个类似的静态 DomainEvents 对象来让我访问发布机制,而实际的实现细节不会泄漏到我的域模型实体中。所以调用是这样的:

DomainEvents.fire(new MySampleEvent(...some params...));

CDI 规范中可用的模式和机制是带有 @Observes 的事件,它允许您使用所有可用服务响应普通 bean 中的某些事件。这类似于我在使用诸如Castle Windsor之类的 DI 框架时所习惯的,我可以通过接口注册通用处理程序。所以我已经涵盖了观察者(处理程序、侦听器,无论你想怎么称呼他们)。例子:

@Stateless
public class MySampleEventObserver {

  public void listen(@Observes MySampleEvent event) {
    ...
    doSomethingWithEvent();
  }
}

现在是发布(在 CDI 中触发)部分。由于无法访问实体中的 CDI(有充分的理由!)我决定使用 JNDI 和BeanManager。我使用 JNDI 来获取 BeanManager 并使用它的fireEvent方法。将 bean 管理器解析(如此处所示)放入代码中:

public class BeanHelper {
  public static BeanManager getBeanManager() {
    try {
        InitialContext initialContext = new InitialContext();
        return (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        e.printStackTrace();
        return null;
    }
  }

}

最后一步是 DomainEvents 对象本身:

public class DomainEvents {

  private static boolean mNopMode = false;

  public static void setNopMode() {
    mNopMode = true;
  }

  public static void reset() {
    mNopMode = false;
  }

  public static <TDomainEvent> void fire(TDomainEvent event) {
    if (mNopMode) {
        return;
    }
    BeanManager manager = BeanHelper.getBeanManager();

    manager.fireEvent(event);
  }

}

当没有上下文时,setNopModeand部分用于测试目的。reset基本上是手动模拟。在单元测试之前将其设置为 NOP 操作模式并在它们之后重置。

作为 POC 工作正常。不知道它的使用是否有任何严重的限制。我留下了异步总线交互,类似于监听器的实现。

希望有任何评论。

于 2013-04-12T08:59:45.567 回答
1

我目前正在考虑使用 Google 的Guava EventBus来做类似于您参考的“拯救”文章的事情。

使用它类似于“如何引发域事件”看起来像这样,几乎与文章完全相同:

public class Customer
{
    public void DoSomething()
    {
        MyEventBus.post(new CustomerBecamePreferred() { Customer = this });
    }
}

我不知道您是否认为这是“Udi Dahan 的领域事件模式的实现”。

它不需要实现任何接口;事件处理程序标有注释,并且类在 EventBus 中注册MyEventBus.register(aListenerObject)

于 2012-04-18T20:18:58.553 回答