在Vaadin应用程序中,我计划为方法实现异步结果概述。
结果概述包含可能结果的表格。当后端方法在线程中异步运行时,应生成这些结果。使用CDI-Events计划应用程序的后端和前端之间的通信(结果的信息将在CDI-Event中)。
我已经实现了触发CDI-Events,将它们放入结果表并在方法完成后显示表。但是当我在一个线程中执行该方法时(因此显示视图并插入事件而不是等待查看完整的表),我的CDI-Events不会触发(或者被接收)。
有没有办法解决这个问题?我读到了异步接收CDI事件(blog entry),但我没有找到关于在线程中触发事件的任何内容......
WildFly 10.0.1.Final,Java 8,Java-EE 7和Vaadin 7.6.6。
线程,它应该触发CDI-Events:
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-Events的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);
}
答案 0 :(得分:0)
在CDI 1.2及更低版本中,事件严格同步。在CDI 2.0中已经有一个异步事件的实现版本(在Weld中),但我想你已经陷入了1.2。
这意味着(正如您阅读的博客文章所示),您可以利用臭名昭着的EJB。
至于为什么CDI在这种情况下不起作用 - 我会说这是所有线程绑定的。换句话说,在您触发事件的给定线程中,您没有被触发的观察者。