gpt4 book ai didi

jsf - 在另一个 View 范围 bean 中注入(inject)一个 View 范围 bean 会导致它被重新创建

转载 作者:行者123 更新时间:2023-12-04 10:08:52 27 4
gpt4 key购买 nike

我需要在另一个 View 范围 bean 中使用保存在 View 范围 bean 中的一些数据。

@ManagedBean
@ViewScoped
public class Attivita implements Serializable {
//
}


@ManagedBean
@ViewScoped
public class Nota implements Serializable {

@ManagedProperty("#{attivita}")
private Attivita attivita;

// Getter and setter.
}

现在,也许我关于它的理论仍然很差,我注意到当 #{attivita}注入(inject), Attivita构造函数被调用,从而创建另一个实例。这是正确的行为吗?如果我想引用同一个实例而不创建一个新实例怎么办?

最佳答案

如果您在回发中从一个 View 导航到另一个 View ,就会发生这种情况。 View 范围的 bean 不绑定(bind)到请求,而是绑定(bind)到 View 。因此,当您导航到新 View 时,它将获得 View 范围 bean 的全新实例。它不会重用与前一个 View 关联的同一个 bean 实例。

我了解 attivita bean 在初始 View 上创建并在回发时重用。我了解 nota bean 与您要导航到的新 View 相关联。注入(inject)时attivita在其中,即使在同一个请求中有另一个实例,它也会简单地获得一个新的和不同的实例。这是所有预期的(并且诚然有点不直观)的行为。

对此没有标准的 JSF 解决方案。 CDI 通过 @ConversationScoped 解决了这个问题(只要您明确告诉它存在,bean 就会存在)并且 CDI 扩展 MyFaces CODI 使用 @ViewAccessScoped 更进一步(只要导航 View 引用它,bean 就会存在)。

但是,您可以通过将 bean 作为属性存储在请求范围中来解决此问题。

@ManagedBean
@ViewScoped
public class Attivita implements Serializable {

public String submit() {
FacesContext.getCurrentInstance().getExternalContext()
.getRequestMap().put("attivita", this);
return "nota";
}

}


@ManagedBean
@ViewScoped
public class Nota implements Serializable {

private Attivita attivita;

@PostConstruct
public void init() {
attivita = (Attivita) FacesContext.getCurrentInstance().getExternalContext()
.getRequestMap().get("attivita");
}

}

请注意,这是相当hacky。根据具体的功能要求,可能会有更好的解决方案。另请注意,您应该在 nota查看引用所需 Attivita bean 实例为 #{nota.attivita}而不是 #{attivita} ,因为它会给你一个新的和不同的实例,原因之前已经解释过了。

关于jsf - 在另一个 View 范围 bean 中注入(inject)一个 View 范围 bean 会导致它被重新创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14231044/

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