为什么bean构造函数被调用两次?

时间:2015-01-22 16:32:50

标签: jsf constructor managed-bean

为什么'UserBean'被创建两次?当我第一次访问该页面时会发生这种情况。接下来,bean创建一次。它有一个默认的构造函数,系统输出。那么为什么会这样呢?

<h:body>
    <h3>#{userBean.requestParametr}</h3>

    <h:form id="form">
        <p:panel id="panel">
            <h:panelGrid columns="3">
                <h:outputLabel for="email" value="E-mail: " />

                <p:inputText id="email"
                             value="#{userBean.email}"
                             required="true"
                             label="E-mail">
                </p:inputText>

                <h:outputLabel for="password" value="#{msg['_password']}: " />

                <p:inputText type="password" id="password"
                             value="#{userBean.password}"
                             label="#{msg['_password']}"
                             required="true">
                </p:inputText>
            </h:panelGrid>

            <p:commandButton id="btn" value="#{msg['_enter']}" update="panel"
                             action="#{userBean.login}" />
        </p:panel>
    </h:form>
</h:body>

1 个答案:

答案 0 :(得分:1)

  

它有一个默认构造函数,系统输出

当您使用使用代理的bean管理框架(例如CDI)(即bean使用@Named注释时)会发生这种情况,这也可以通过查看previous question来确认)。它在首次使用期间创建一个实例,以便在创建代理之前检查实例。所有后续实例化都通过代理类完成。

你至少不应该在bean构造函数中做任何事情。相反,如果您打算挂钩托管bean初始化,请使用注释为@PostConstruct的方法。并且,如果您打算挂钩托管bean销毁,请使用带@PreDestroy注释的方法。

@Named
public class Bean {

    @PostConstruct
    public void init() {
        // ...
    }

    @PreDestroy
    public void destroy() {
        // ...
    }

}

方法名称可供您自由选择。以上只是规范名称,取自几个现有的API,例如servlet和过滤器,从而提高了代码的自我可记录性。