【问题标题】:Constructor of CDI managed bean is invoked twice while opening the page打开页面时调用了两次 CDI 托管 bean 的构造函数
【发布时间】:2013-09-20 07:58:01
【问题描述】:

我正在尝试使用来自 PrimeFaces 的 ChartBean 示例。这是视图:

<h:form>
    <p:layoutUnit position="center">             
    <p:lineChart id="linear" value="#{chartBean.linearModel}" legendPosition="e"
        title="Linear Chart" minY="0" maxY="1000" style="height:600px"/>                        
    </p:layoutUnit>
</h:form>

这是豆子:

@Named
@RequestScoped
public class ChartBean implements Serializable {

    private CartesianChartModel categoryModel;
    private CartesianChartModel linearModel;

    public ChartBean() {
        System.out.println("ChartBean constructed");
        createCategoryModel();
        createLinearModel();
    }

    // ...
}

当我运行它时,我注意到这个 bean 的构造函数在打开页面时被调用了两次。日志显示如下:

信息:ChartBean 构造
信息:ChartBean 构造

所以 bean 被实例化了两次。这是如何引起的,我该如何避免呢?我正在与 DB 交互以获取一些数据以在 UI 中显示,这样就不必要地获取了两次数据。

【问题讨论】:

    标签: jsf primefaces constructor cdi glassfish-4


    【解决方案1】:

    第一个创建是创建 bean 范围代理的容器。作用域代理是一个扩展您的 bean 的对象,并在其他组件需要您的 bean 时被注入。然而,它的方法并不执行真正的逻辑,而是将它们的执行委托给你的 bean 的正确的 contectual 实例。举个例子就明白了:

    假设有 2 个请求,R1,R2。 ChartBean 必须有 2 个实例,B1 和 B2。假设另一个组件 C 依赖于ChartBean。 C的相关字段必须在应用程序初始化时注入ChartBean的实例,并在执行时调用正确的bean实例。但是在应用程序初始化时没有请求,当然也没有 B1、B2。容器有什么作用?它创建作用域代理并将其注入任何需要它的人。然后,无论何时调用ChartBean.method(),它都会在代理上调用,代理决定哪个是要调用的正确bean(B1 代表R1,B2 代表R2,如果没有活动请求则抛出异常,例如从MessageDrivenBean 调用)。

    如上所述:不要在 JAVA EE 组件中的构造函数中运行业务逻辑,因为构造函数可能会从系统/容器中调用。请改用@PostConstruct 方法:

    ...
    public class ChartBean implements Serializable {
        public ChartBean() {
            // only construction logic here
        }
        ...
        @PostConstruct
        void postConstruct() {
            createCategoryModel();
            createLinearModel();
        }
    }
    

    顺便说一句,您可以通过在构造函数中打印类名来验证构造函数是从代理实现调用的:

        public ChartBean() {
            System.out.println("ChartBean as " + this.getClass().getName());
        }
    

    第一次被调用时,它会是你自己的其他类。

    【讨论】:

    • 确实 ChartBean 为 ec.europa.eu.sep.statisticsep.ChartBean$Proxy$_$$_WeldClientProxy 信息:ChartBean 为 ec.europa.eu.sep.statisticsep.ChartBean
    猜你喜欢
    • 2013-09-04
    • 1970-01-01
    • 2013-05-23
    • 2013-08-25
    • 2019-08-02
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2019-05-09
    相关资源
    最近更新 更多