@Asynchronous CDI事件和@Named bean中的@Observes方法

时间:2016-05-09 13:48:05

标签: jsf events asynchronous cdi

我有CDI事件来通知我的JSF应用程序EJB进程的进度。当一切都是同步时,代码工作正常。

@Stateless
public class MySessionBean implements Serializable {

    @Inject
    @ProcessEvent
    Event<ProcessEvent> processEvent; // Also tried to use BeanManager

    @Asynchronous // This annotation breaks my code
    public void runLongProcess() {
        processEvent.fire(new ProcessEvent());
    }

}

@Named
@ViewScoped
public class ManagedBean implements Serializable {

    @EJB
    MySessionBean sessionBean;

    public void runProcess () {
        sessionBean.runLongProcess();
    }

    @Asynchronous // This annotation doesn't work
    public void onEvent(@Observes @ProcessEvent ProcessEvent event){
        LOGGER.log(Level.INFO, "Event was received"); // Never called
    }
}

如果我在@Asychronous上使用runLongProcess()注释,则永远不会调用JSF @Observer方法。

如何实现此功能?

JSF 2.2 Glassfish 3.1 JEE 7 Java 8 Omnifaces 2.3

1 个答案:

答案 0 :(得分:4)

在那个时刻和该线程中,任何地方都不一定有HTTP请求。因此,当时不一定有可用/可识别的JSF视图(更不用说HTTP请求或会话)。

它将在应用程序作用域中运行。

鉴于您正在使用OmniFaces 2.3,可能值得花些时间查看<o:socket>以解决您的需求。它的文档也描述了这种情况以及如何在回调的帮助下正确解决它(并通过Web套接字将结果推送到视图中)。

@Inject
private SomeService someService;

@Inject @Push
private PushContext someChannel;

public void someAction() {
    someService.someAsyncServiceMethod(entity, message -> someChannel.send(message));
}

@Asynchronous
public void someAsyncServiceMethod(Entity entity, Consumer<Object> callback) {
    // ... (some long process)
    callback.accept(entity.getSomeProperty());
}