跨会话范围的 JSF 支持 bean 观察 CDI 事件吗
我想知道是否可以使用多个 JSF 2.0 会话范围的支持 bean 来观察 CDI 事件。我认为我可以通过观察事件将事件/数据推送到多个会话。
我设置了一个小测试,允许用户使用页面上的按钮来触发事件(该按钮与会话范围的支持 bean 中实际触发事件的方法绑定)。我认为如果我打开两个不同的浏览器,将创建两个会话,并且该事件将通知每个会话范围的支持 bean。
然而,当运行我的小测试并单击按钮在其中一个浏览器上触发事件时,我发现该事件仅通知会话范围的 bean 之一。它只通知触发事件的 bean(即,如果我单击浏览器 1 中的按钮,则通知浏览器 1 中支持会话的会话范围 bean,如果我单击浏览器 2 中的按钮,则支持浏览器 2 中的会话的 bean浏览器 2 收到通知)。
我的印象是事件会通知所有 bean 实例。然而,情况似乎并非如此。我应该能够做到这一点吗?我只是设置错误吗?
更新显示我的代码如下:
用于触发事件并显示会话范围数据的jsfpage.xhtml片段:
<h:form>
<h:outputText value="#{BackingBean.property}" />
<p:commandButton value="Fire Event" action="#{EventFirer.fireEvent}" />
</h:form>
接收事件的会话范围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;
}
}
I'm wondering if it is possible to observe a CDI event with multiple JSF 2.0 session scoped backing beans. I thought that I could push event/data to multiple sessions by observing the event.
I've set up a small test that allows the user to fire the event using a button on the page (which is tied to a method in the session scoped backing bean that actually fires the event). I thought that if I opened two different browsers, two sessions would be created and the event would notify each of the session scoped backing beans.
However, when running my little test and clicking the button to fire the event on one of the browsers, I see that the event only notifies one of the session scoped beans. It only notifies the bean from which the event was fired (i.e. - if I click the button in browser 1 the session scoped bean backing the session in browser 1 is notified, and if I click the button in browser 2 the bean backing the session in browser 2 is notified).
I was under the impression that events would notify all bean instances. However, this doesn't seem to be the case. Should I be able to do this? Do I just have something setup wrong?
UPDATE to show what my code looks like:
A snippet of jsfpage.xhtml to fire an event and show the session-scoped data:
<h:form>
<h:outputText value="#{BackingBean.property}" />
<p:commandButton value="Fire Event" action="#{EventFirer.fireEvent}" />
</h:form>
The Session-scoped bean that receives event:
@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();
}
}
An application scoped bean to fire the event:
@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;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您最好指定事件的类型:
除此之外,规范中没有任何指示会限制调用观察者方法的 bean 实例。我会就此提出一个问题(在您正在使用的实现的错误跟踪器中。也许是 Weld?)
First, you'd better specify the type of the event:
Apart from that there is no indication in the spec that would limit the bean instances on which the observer method is invoked. I'd file an issue about this (in the bugtracker of the implementation you are using. Perhaps Weld?)
我发现所有注册的观察员都被解雇了。
最值得注意的是,如果我在对话范围 bean 上有一个观察者,并且该 bean 在当前对话中不活动,那么当事件被触发时,会专门创建一个新实例来接收它!
I've found that all registered observers are fired.
Most notably if I have an observer on a Conversation Scoped bean and that bean is not active in the current Conversation then, when the event is fired, a new instance is created specially to receive it!