Jsf 将一个视图范围的bean注入另一个视图范围的bean会导致重新创建它

Jsf 将一个视图范围的bean注入另一个视图范围的bean会导致重新创建它,jsf,jsf-2,dependency-injection,managed-bean,Jsf,Jsf 2,Dependency Injection,Managed Bean,我需要在另一个视图范围bean中使用保存在视图范围bean中的一些数据 @ManagedBean @ViewScoped public class Attivita implements Serializable { // } 及 现在,也许我关于它的理论还很差,我注意到当注入{attivita}时,调用attivita构造函数,从而创建另一个实例。这是正确的行为吗?如果我想引用同一个实例而不创建新实例呢?您的attivitabean是@viewscope的,这并不保证您的实例将在会话

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

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


现在,也许我关于它的理论还很差,我注意到当注入
{attivita}
时,调用
attivita
构造函数,从而创建另一个实例。这是正确的行为吗?如果我想引用同一个实例而不创建新实例呢?

您的
attivita
bean是
@viewscope
的,这并不保证您的实例将在会话中保持。您需要一个
@SessionScoped
bean。但是,如果出于某种原因需要
attivita
成为
@viewscope
,则可以通过其他方式传递参数,例如使用
viewParam
或在它们之间使用其他
@SessionScoped
bean

页面参数

JSF2托管Bean作用域


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

我知道
attivita
bean是在初始视图上创建的,并在回发时重用。我知道
nota
bean与您导航到的新视图相关联。当在其中注入
attivita
时,它只会得到一个新的、不同的实例,即使在同一个请求中还有另一个实例。这都是意料之中的行为(当然也有点不直观)

没有标准的JSF解决方案。CDI通过
@ConversationScoped
解决了这个问题(bean只要你明确告诉它生存就可以生存),CDI扩展MyFaces CODI通过
@ViewAccessScoped
(只要导航视图引用它,bean就可以生存)

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

@ManagedBean
@ViewScoped
public class Attivita implements Serializable {

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

}


请注意,这是相当粗糙的。根据具体的功能要求,可能会有更好的解决方案。还要注意的是,您应该在
nota
视图中将所需的
Attivita
bean实例引用为
{nota.Attivita}
而不是
{Attivita}
,因为它会给您一个新的和不同的实例,原因已经在前面解释过了。

注意标记正确的响应。堆栈溢出不仅与问题有关,还与答案有关。这肯定有效——我也有同样的问题。然而,正如您所说的,它非常粗糙,这是JSF的另一个巨大缺点。当您必须添加PostConstruct并且必须手动从Faces上下文中拉出bean时,它有点消除了CDI或托管属性的用途。是否有计划将@ViewAccessScope添加到标准JSF API中,而不仅仅作为Myfaces的一部分?@GreenieManie:JSF 2.2添加了
@FlowScoped
,以涵盖这一点,但不幸的是,它仍然需要一些XML配置和自动生成的请求参数,因为它还需要在GET请求中生存下来。比如说,它介于
@ViewAccessScoped
@SessionScoped
之间。作为一个可能的“更好的解决方案”,您可以考虑使用实体ID作为param重定向它,或者使用另一个include有条件地呈现同一视图的一部分。另请参见a.o.您是否建议将视图a.xhtml包含到b.xhtml中,并可能将b.xhtml的所有内容包装在一个巨大的ui中:该片段仅在重定向到(通过b.xhtml)时实际呈现任何内容,而不在作为a.xhtml的虚拟引用包含时呈现任何内容?@GreenieMeanie:See.g。(在这个“向导”页面上应用这个想法,而不是在整个站点上)。
@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");
    }

}