为什么@PostConstruct被多次调用

时间:2018-12-12 11:45:42

标签: jsf conversation-scope

我尝试像下面的示例一样构建一个ConversationScoped Bean。该示例摘自《 Java EE 8中的实用JSF》一书:

@Named
@ConversationScoped
public class BookEditor implements Serializable {

    private static final long serialVersionUID = 1L;
    private static Logger logger = Logger.getLogger(BookEditor.class.getName());

    private int counter = 0;

    @Inject
    Conversation _conversation;

    public int getCounter() {
        return counter;
    }

    public void setCounter(int counter) {
        this.counter = counter;
    }

    @PostConstruct
    private void init() {
        logger.info("...init..");
        loadOrCreateBook();
        if (_conversation.isTransient()) {
            _conversation.begin();
            logger.info("...begin conversation..");
        }
    }

    public void count() {
        counter = counter + 1;
        logger.info("...counter=" + counter);
    }

    private void loadOrCreateBook() {
        counter = 0;
    }
}

目标是此bean在页面中仅初始化一次。

示例页面:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="/layout/template.xhtml">

    <ui:define name="content">
        <p>Counter = #{bookEditor.counter}</p>
        <h:form>
            <h:commandLink styleClass="button" value="counter commandLink"
                actionListener="#{bookEditor.count()}"
                action="/pages/bookEditor.xhtml" />
        </h:form>
    </ui:define>
</ui:composition>

我在浏览器中打开带有链接../pages/bookEditor.xhtml的页面,然后多次单击按钮。 Bean创建完成,并开始新的对话。并且计数器增加。日志文件如下所示:

...init..
...begin conversation..
...counter=1
...counter=2
...counter=3

一切都很好。

但是:如果我将计数器信息放置在表单标签中,这是一个典型的用例。...

<ui:define name="content">
    <h:form>
        <p>Counter = #{bookEditor.counter}</p>
        <h:commandLink styleClass="button" value="counter commandLink"
            actionListener="#{bookEditor.count()}"
            action="/pages/bookEditor.xhtml" />
    </h:form>
</ui:define>

...现在,如果我第一次单击该按钮,则对话将第二次开始。日志文件如下所示

...init..
...begin conversation..
...init..
...begin conversation..
...counter=1
...counter=2
...counter=3

为什么会这样?我需要避免第二次初始化。到目前为止,我唯一的解决方案是避免使用@PostConstruct。

0 个答案:

没有答案