@Named bean中的@Asynchronous CDI事件和@Observes方法 [英] @Asynchronous CDI Events and an @Observes method in @Named bean

查看:179
本文介绍了@Named bean中的@Asynchronous CDI事件和@Observes方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  @Stateless 
公共类MySessionBean实现了Serializable {

@注入
@ProcessEvent
Event< ProcessEvent> processEvent; //也尝试使用BeanManager

@Asynchronous //此注释破坏了我的代码
public void runLongProcess(){
processEvent.fire(new ProcessEvent());
}

}

  @Named 
@ViewScoped
公共类ManagedBean实现可序列化{

@EJB
MySessionBean sessionBean;

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

@Asynchronous //此注释无效
public void onEvent(@Observes @ProcessEvent ProcessEvent event){
LOGGER.log(Level.INFO ,已收到事件); //从未调用过
}
}

如果我使用<$ c在$code> runLongProcess()上的$ c> @Asyncchronous 注释中,JSF @Observer 方法是



我如何实现此功能?



JSF 2.2
Glassfish 3.1
JEE 7
Java 8
Omnifaces 2.3

解决方案

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



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

鉴于您使用的是OmniFaces 2.3,值得尝试一下 < o:socket> 即可满足您的需求。它的文档也准确地描述了这种情况,以及如何借助回调正确解决此问题(并通过Web套接字将结果推送到视图)。

  @注入
私人SomeService someService;

@ Inject @Push
private PushContext someChannel;

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

  @异步
public void someAsyncServiceMethod(Entityentity,Consumer< Object>回调){
// ...(有些漫长的过程)
callback.accept( entity.getSomeProperty());
}


I have CDI Events in place to notify my JSF application of progress from EJB processes. The code works fine when everything is synchronous.

@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
    }
}

If I use an @Asychronous annotation on runLongProcess(), the JSF @Observer method is never called.

How can I achieve this functionality ?

JSF 2.2 Glassfish 3.1 JEE 7 Java 8 Omnifaces 2.3

解决方案

There's not necessarily means of a HTTP request anywhere at that moment and in that thread. Therefore, there's not necessarily a JSF view available/identifiable at that moment (let alone a HTTP request or session).

It'll work in an application scoped bean.

Given that you're using OmniFaces 2.3, it might be worth the effort to take a look at <o:socket> to solve the requirement you had in mind. Its documentation also describes exactly this case and how to solve it properly with help of callbacks (and push the result via a web socket to the view).

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

这篇关于@Named bean中的@Asynchronous CDI事件和@Observes方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆