gpt4 book ai didi

jsf - 打开页面时调用了两次 CDI 托管 bean 的构造函数

转载 作者:行者123 更新时间:2023-12-01 07:39:36 25 4
gpt4 key购买 nike

我正在尝试使用 ChartBean来自 PrimeFaces 的样本。这是 View :

<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>

这是 bean :
@Named
@RequestScoped
public class ChartBean implements Serializable {

private CartesianChartModel categoryModel;
private CartesianChartModel linearModel;

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

// ...
}

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

INFO: ChartBean constructed
INFO: ChartBean constructed



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

最佳答案

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

假设 2 个请求,R1,R2。 ChartBean 必须有 2 个实例, B1 和 B2。假设另一个组件 C 依赖于 ChartBean . C的相关字段必须注入(inject)ChartBean的实例在应用程序初始化时并在执行时调用正确的 bean 实例。但是在应用程序初始化时没有请求,当然也没有 B1、B2。容器有什么作用?它创建作用域代理并将其注入(inject)任何需要它的人。然后,每当 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());
}

第一次调用它时,它将是您自己的其他类。

关于jsf - 打开页面时调用了两次 CDI 托管 bean 的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18911646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com