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

Why is the bean constructor called twice?

为什么 '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>

It has a default constructor with system out

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

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

@Named
public class Bean {

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

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

}

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