@SessionScoped bean 一遍又一遍地实例化

@SessionScoped bean instantiated over and over

使用 PrimeFaces 5.10、JSF 2 和 Wildfly,我试图让我的 xhtml 页面与带有 PF 轮询组件的 @SessionScoped bean 的单个实例进行交互。每次轮询调用 bean 方法时,都会创建一个新的 bean 实例。我已经尝试过@ViewScoped 和@SessionScoped,但行为没有任何变化。我注意到其他类似的问题,但没有看到任何我能够实施的解决方案。

我知道 println 不是显示方法调用顺序的可靠方法,但我使用它们只是为了演示正在调用哪些方法,而且似乎 init() 方法被一遍又一遍地调用,即使我有@PostConstruct,所以它是新的实例化。我什至正在打印 "this" 并且每次打印时它都显示不同的哈希值。

它永远不会通过 refreshTweets() 中的 if 语句,因为 stopPolling 字段永远不会在正确的上下文中设置为 false。

我以前 运行 遇到过这个问题,并且能够解决它而不是解决它。如果有人对我做错了什么有任何想法,请告诉我。

下面是相关的xhtml代码:

<p:layoutUnit id="center" position="center" styleClass="dataBox">
    <h:form id="TwitterFeed">
        <p:panelGrid columns="2">
            <p:outputLabel value="Twitter topic to query: " />
            <p:inputText value="#{dataBean.tweetTopic}"/>
            <p:outputLabel value="Number of Twitter Results: " />
            <p:inputText value="#{dataBean.tweetCount}" />
            <p:commandButton value="Submit" action="#{dataBean.toggleRenderTweets}" update="tweets"/>
            <p:commandButton value="Polling" action="#{dataBean.togglePolling}" update="tweets"/>                           
        </p:panelGrid>
        <p:panel visible="#{dataBean.renderTweets}" id="tweets">
            <p:panelGrid columns="1">
                <p:dataTable id="twitterTable" value="#{dataBean.tweetList}" var="tweetStatus">
                    <p:columns value="#{dataBean.tweetColumns}" var="column" columnIndexVar="colIndex">
                        <f:facet name="header">
                            <h:outputText value="#{column.header}"/>
                        </f:facet>
                        <h:outputText value="#{tweetStatus[column.property]}"/>
                    </p:columns>
                </p:dataTable>
                <p:poll interval="10" listener="#{dataBean.refreshTweets}" update="twitterTable" widgetVar="tweetPoll" id="tweetPoll" autoStart="true"/>
            </p:panelGrid>
        </p:panel>
    </h:form>        
</p:layoutUnit>

相关bean代码如下:

import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.annotation.PostConstruct;
import java.io.Serializable;

@SessionScoped
@ManagedBean
public class DataBean implements Serializable {

    private List<TwitterStatusModel> tweetList;
    private boolean renderTweets;
    private boolean stopPolling;


    @PostConstruct
    public void init() {
        <<initialize fields>>
        stopPolling = true;
        System.out.println(this + " init()");
    }

    private void getTweets() {
       <<this method sets the List above tweetList>>
    }

    public void refreshTweets() {
        if (!stopPolling) {
            <<Method never passes the if statement because stopPolling is set to true in init()
        }

    public void togglePolling() {
        stopPolling = !(stopPolling);
        System.out.println(this + "Toggling polling - now " + stopPolling);
    }

您应该使用正确的@SessionScoped 等导入。 使用@ManagedBean,您需要 javax.faces.bean.* 而不是 javax.enterprise.context 或 javax.faces.view

另见 Why are there different bean management annotations