我正在寻找 Udi Dahan 的域事件模式和基础设施的简单 Java 实现,如本文所述。
这很简单,我已经实现了自己的解释,但是我是 Java 新手,不想因为缺乏语言经验而被任何错误所困扰。
我发现的唯一 Java 实现是在Jdon Framework中,但对于我目前的项目来说,它有点过于重量级了。
谢谢!
我正在寻找 Udi Dahan 的域事件模式和基础设施的简单 Java 实现,如本文所述。
这很简单,我已经实现了自己的解释,但是我是 Java 新手,不想因为缺乏语言经验而被任何错误所困扰。
我发现的唯一 Java 实现是在Jdon Framework中,但对于我目前的项目来说,它有点过于重量级了。
谢谢!
一段时间以来,我一直在寻找 Java EE 中相同问题的解决方案。我查看了Axon和jdon(该页面也不是很好的预兆 :))。两者都涉及事件采购,我无法将其“出售”给我的雇主/客户。不过,我想拥有领域事件,因为我在 .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);
}
}
当没有上下文时,setNopMode
and部分用于测试目的。reset
基本上是手动模拟。在单元测试之前将其设置为 NOP 操作模式并在它们之后重置。
作为 POC 工作正常。不知道它的使用是否有任何严重的限制。我留下了异步总线交互,类似于监听器的实现。
希望有任何评论。
我目前正在考虑使用 Google 的Guava EventBus来做类似于您参考的“拯救”文章的事情。
使用它类似于“如何引发域事件”看起来像这样,几乎与文章完全相同:
public class Customer
{
public void DoSomething()
{
MyEventBus.post(new CustomerBecamePreferred() { Customer = this });
}
}
我不知道您是否认为这是“Udi Dahan 的领域事件模式的实现”。
它不需要实现任何接口;事件处理程序标有注释,并且类在 EventBus 中注册MyEventBus.register(aListenerObject)