j-d*_*ion 0 java jboss cdi java-ee-7 wildfly
我有一个在 JBoss/Wildfly 上运行的应用程序。我使用 CDI 事件在模块之间进行通信。我希望能够使用事件作为插入自定义的一种方式,基本上动态加载一个额外的观察者,该观察者也将接收 CDI 事件。
这是我用来从 EJB 中动态加载类的片段:
File file = new File("D:\\workspace\\integrator\\target\\classes\\");
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
Class cls = cl.loadClass("demo.DemoObserver");
observerInstance=cls.newInstance();
Run Code Online (Sandbox Code Playgroud)
加载的类非常简单,只是一个普通的 CDI 事件观察器,注释为 @Dependent 以“看到”为一个 bean。我的 beans.xml 被配置为自动发现 bean。
@Dependent
public class DemoObserver {
private boolean observed=false;
public DemoObserver() {
observed=false;
}
@PermitAll
public void stateChanged(@Observes EquipmentE10StateChanged event) {
observed=true;
System.out.println("Demo observer received event E10 state changed: " + event.toString());
}
}
Run Code Online (Sandbox Code Playgroud)
该类已加载并实例化(我可以看到来自其构造函数的日志),但它从不接收事件。
有什么我可以做的事情吗?
有很多方法可以回答真正被问到的问题,但目前我会坚持提出问题。
因为 CDI 强调类型安全,它在启动时计算 bean(和观察者方法等)之间的连接,然后将其锁定。因此,一般而言,如果您有一个被注释为 bean 的类,并且无论出于何种原因它在启动时都没有“看到”,那么您就不能“让它”在以后“看到”。如果在运行可移植扩展并且容器启动并运行之后,您有四个观察者方法,那么这永远是将存在的观察者方法总数。这是设计使然。
(此外,在您的示例中,您可能确实有一个 bean 类,但您是通过自己的newInstance()调用手动创建它的。在 CDI 中,一般来说,如果您正在使用 做某事new,那么您可能做错了™某种程度。)
这意味着假设您在启动时一无所知,您将需要一个观察者方法来观察您感兴趣的最抽象的事件,然后对真正需要通知的任何事件进行动态调度.
或者,如果你在启动时知道潜在观察者的“封闭世界” ——也许有EquipmentE10观察者和EquipmentE09观察者,仅此而已——你可以创建一个适合他们每个人的观察者方法,并使用事件子类型和限定符的某种组合来选择哪些会得到通知。但是,请注意事件限定符和有效载荷有点违反直觉。
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |