在会话作用域的JSF支持bean中观察CDI事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在会话作用域的JSF支持bean中观察CDI事件相关的知识,希望对你有一定的参考价值。

我想知道是否有可能观察到多个JSF 2.0会话作用域支持bean的CDI事件。我以为我可以通过观察事件将事件/数据推送到多个会话。

我已经设置了一个小测试,允许用户使用页面上的按钮触发事件(它与会话范围的支持bean中实际触发事件的方法相关联)。我认为,如果我打开两个不同的浏览器,将创建两个会话,并且事件将通知每个会话范围的支持bean。

但是,当运行我的小测试并单击按钮以在其中一个浏览器上触发事件时,我看到该事件仅通知其中一个会话范围的bean。它只通知触发事件的bean(即 - 如果我单击浏览器1中的按钮,则会通知浏览器1中支持会话的会话范围bean,如果我单击浏览器2中的按钮,则支持会话的bean浏览器2被通知)。

我的印象是事件会通知所有bean实例。但是,情况似乎并非如此。我应该能做到吗?我只是设置错误吗?

更新以显示我的代码:

用于触发事件并显示会话范围数据的jsfpage.xhtml片段:

<h:form>
  <h:outputText value="#{BackingBean.property}" />
  <p:commandButton value="Fire Event" action="#{EventFirer.fireEvent}" />
</h:form>

接收事件的Session-scoped bean:

@Named
@SessionScoped
public class BackingBean implements Serializable {

    private String property;

    public String getProperty() {
        return property
    }

    public void listenForChange(@Observes EventObj event) {
        logger.log(Level.INFO, "Event received");
        property = event.toString();
    }
}

用于触发事件的应用程序作用域bean:

@Named
@ApplicationScoped
public class EventFirer implements Serializable {

    @Inject
    private Event<EventObj> events;

    public String fireEvent() {
        logger.log(Level.INFO, "Event fired");
        events.fire(new EventObj());
        return null;
    }
}
答案

首先,您最好指定事件的类型:

@Inject
private Event<EventObj> events;

除此之外,规范中没有任何指示会限制调用observer方法的bean实例。我提出了一个关于这个的问题(在你正在使用的实现的bugtracker中。也许焊接?)

另一答案

我发现所有注册的观察员都被解雇了。

最值得注意的是,如果我在Conversation Scoped bean上有一个观察者,并且该bean在当前的Conversation中没有活动,那么当事件被触发时,会专门创建一个新实例来接收它!

以上是关于在会话作用域的JSF支持bean中观察CDI事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JSF 页面加载之前在支持 bean 中启动特殊的 init 事件?

会话范围和 jsf 重定向

将 JSF 托管 bean 迁移到 CDI 托管 bean

CDI 托管 bean 和 JSF 托管 bean 可以相互通信吗?

为什么GlassFish 5.1.0中的JSF将我的@ViewScoped CDI bean的ID属性设置为null?

其他 servlet 可以访问 jsf 应用程序中的 cdi bean 吗?