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

@Asynchronous CDI Events and an @Observes method in @Named bean

我有 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
    }
}

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

如何实现此功能?

JSF 2.2 玻璃鱼 3.1 JEE 7 Java 8 全脸 2.3

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

它将在应用程序范围的 bean 中工作。

鉴于您使用的是 OmniFaces 2.3,可能值得努力看看 <o:socket> 来解决您的需求。它的文档还准确描述了这种情况以及如何在回调的帮助下正确解决它(并通过网络套接字将结果推送到视图)。

@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());
}