在一个线程中触发 CDI-Events
Firing CDI-Events within a thread
在 Vaadin 应用程序中,我计划为方法实现异步结果概览。
结果概览包含 table 可能的结果。这些结果应该在后端方法在线程中 运行 异步时生成。应用程序后端和前端之间的通信计划使用 CDI-Events(结果信息将在 CDI-Event 中)。
我已经实现了触发 CDI-Events,将它们放入结果-table 并在方法完成后显示 table。但是当我在一个线程中执行该方法时(因此显示视图并插入事件而不是等待看到完整的 table),我的 CDI-Events 不会触发(或收到)。
有什么办法可以解决这个问题吗?我阅读了有关接收异步 CDI 事件的信息 (blog entry),但我没有找到任何有关在线程内触发事件的信息...
WildFly 10.0.1.Final、Java 8、Java-EE 7 和 Vaadin 7.6.6.
应该触发 CDI 事件的线程:
public class Executer implements Runnable{
@Override
public void run(){
// Here will be the backend-method invocation for firing CDI-Events
// CDI-Dummy-Event - Does not fire properly. receiveStatusEvent() does not invoke
BeanManager beanManager = CDI.current().getBeanManager();
beanManager.fireEvent(new ResultEvent("Result event example"));
}
}
接收 CDI 事件的 Bean
public class EventReceiver implements LoggingProvider{
public EventReceiver(){
}
public void receiveStatusEvent(@Observes ResultEvent event) {
this.info("Event received: " + event.toString());
}
}
在 ManagedExecutorService 的帮助下启动线程
public void executeAsynchBackendMethod(){
// CDI-Dummy-Event works - receiveStatusEvent() invokes correctly
BeanManager beanManager = CDI.current().getBeanManager();
beanManager.fireEvent(new ResultEvent("Result event example"));
/* The following alternative starts a thread, but the events, which are fired in the run() method, do not take any action in the receiveStatusEvent() method */
// Getting managedExecuterService
this.managedExecuterService = (ManagedExecutorService) new InitialContext().lookup("java:comp/DefaultManagedExecutorService");
// Getting Instance of executer-Runnable (for injecting the backend-service afterwards)
Instance<Executer> executerInstance = CDI.current().select(Executer.class);
Executer executer = executerInstance.get();
// Start thread
this.managedExecuterService.submit(executer);
}
在 CDI 1.2 及更低版本中,事件是严格同步的。在 CDI 2.0 中已经有异步事件的实现版本(在 Weld 中),但我想你被 1.2 困住了。
这意味着(正如您阅读的博客 post 所建议的那样),您可以使用声名狼藉的 EJB。
至于为什么 CDI 在这种情况下不起作用 - 我会说这都是线程绑定的。换句话说,在您触发事件的给定线程中,您没有观察者被触发。
在 Vaadin 应用程序中,我计划为方法实现异步结果概览。
结果概览包含 table 可能的结果。这些结果应该在后端方法在线程中 运行 异步时生成。应用程序后端和前端之间的通信计划使用 CDI-Events(结果信息将在 CDI-Event 中)。
我已经实现了触发 CDI-Events,将它们放入结果-table 并在方法完成后显示 table。但是当我在一个线程中执行该方法时(因此显示视图并插入事件而不是等待看到完整的 table),我的 CDI-Events 不会触发(或收到)。
有什么办法可以解决这个问题吗?我阅读了有关接收异步 CDI 事件的信息 (blog entry),但我没有找到任何有关在线程内触发事件的信息...
WildFly 10.0.1.Final、Java 8、Java-EE 7 和 Vaadin 7.6.6.
应该触发 CDI 事件的线程:
public class Executer implements Runnable{
@Override
public void run(){
// Here will be the backend-method invocation for firing CDI-Events
// CDI-Dummy-Event - Does not fire properly. receiveStatusEvent() does not invoke
BeanManager beanManager = CDI.current().getBeanManager();
beanManager.fireEvent(new ResultEvent("Result event example"));
}
}
接收 CDI 事件的 Bean
public class EventReceiver implements LoggingProvider{
public EventReceiver(){
}
public void receiveStatusEvent(@Observes ResultEvent event) {
this.info("Event received: " + event.toString());
}
}
在 ManagedExecutorService 的帮助下启动线程
public void executeAsynchBackendMethod(){
// CDI-Dummy-Event works - receiveStatusEvent() invokes correctly
BeanManager beanManager = CDI.current().getBeanManager();
beanManager.fireEvent(new ResultEvent("Result event example"));
/* The following alternative starts a thread, but the events, which are fired in the run() method, do not take any action in the receiveStatusEvent() method */
// Getting managedExecuterService
this.managedExecuterService = (ManagedExecutorService) new InitialContext().lookup("java:comp/DefaultManagedExecutorService");
// Getting Instance of executer-Runnable (for injecting the backend-service afterwards)
Instance<Executer> executerInstance = CDI.current().select(Executer.class);
Executer executer = executerInstance.get();
// Start thread
this.managedExecuterService.submit(executer);
}
在 CDI 1.2 及更低版本中,事件是严格同步的。在 CDI 2.0 中已经有异步事件的实现版本(在 Weld 中),但我想你被 1.2 困住了。
这意味着(正如您阅读的博客 post 所建议的那样),您可以使用声名狼藉的 EJB。
至于为什么 CDI 在这种情况下不起作用 - 我会说这都是线程绑定的。换句话说,在您触发事件的给定线程中,您没有观察者被触发。