2011-08-02 57 views
3

我的問題是我的ViewScoped bean之一是在同一視圖中多次創建的。每次我在樹中選擇一個節點時,都會創建ViewScopedBean的構造函數。JSF 2.0 ViewScoped生命週期

<h:form> 
    <p:tree value="#{treeBean.root}" var="node" 
     selectionMode="single" selection="#{viewScopedBean.selectedNode}"> 
     <p:ajax event="select" update="selectedNode, treeBeanUpdate, otherBeanUpdate, panel" listener="#{treeBean.onNodeSelect}" /> 
     <p:treeNode> 
      <h:outputText value="#{node}" /> 
     </p:treeNode> 
    </p:tree> 
    Selected Node: <h:outputText value="#{viewScopedBean.selectedNode}" id="selectedNode"/><br/> 
    Current TreeBean: <h:outputText value="#{treeBean}" id="treeBeanUpdate"/><br/> 
    Current OtherBean: <h:outputText value="#{viewScopedBean}" id="otherBeanUpdate"/><br/> 
    <p:outputPanel id="panel"> 
     <ag:profileComponent managedBean="#{viewScopedBean.profileBean}"/> 
    </p:outputPanel> 
</h:form> 

如果刪除該部分(參照複合部件)中,ViewScopedBean構造不調用:

<p:outputPanel id="panel"> 
     <ag:profileComponent managedBean="#{viewScopedBean.profileBean}"/> 
    </p:outputPanel> 

所用的所有豆被設定爲@ViewScoped

@ManagedBean 
@ViewScoped 
public class ViewScopedBean implements Serializable { 

    private TreeNode selectedNode; 
    private ProfileBean profileBean; 

    public ViewScopedBean() { 
     System.out.println("Constructor of ViewScopedBean " + this); 
    } 

    @PostConstruct 
    public void init() { 
     System.out.println("ViewScoped init" + this); 
     profileBean = new ProfileBean(); 
    } 
} 

這是正確的行爲嗎?如果不是什麼可能導致它?

更新:我試圖使用一個空的複合,我有同樣的問題。

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:f="http://java.sun.com/jsf/core"  
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:composite="http://java.sun.com/jsf/composite"> 

     <composite:interface> 
      <composite:attribute name="managedBean" required="true"/> 
     </composite:interface> 

     <composite:implementation> 
     </composite:implementation> 

</html> 

但是,如果我使managedBean不需要,那很好。

我不明白的另一件事是調用構造函數時,似乎創建的對象不被使用。

發起所述視圖(控制檯輸出):

Constructor of ViewScopedBean [email protected] 

2次點擊的樹:

Constructor of ViewScopedBean [email protected] 
Constructor of ViewScopedBean [email protected] 

然後我打開調試窗口<ui:debug/>,所述viewScopedBean設置爲[email protected]

+0

嗯。這非常有趣。你可以嘗試在第二個(或第三個)實例化時拋出異常嗎?很高興看到堆棧跟蹤並看到WHO正在創建ViewScopedBean以及在哪裏。 – fdreger

+0

如果我禁用了部分狀態保存,構造函數實際上只調用一次。 – Sydney

+0

[這個答案](https://stackoverflow.com/questions/15265433/how-and-when-is-a-view-scope-bean-destroyed-in-jsf/15391453#15391453)的問題*「如何何時在JSF中銷燬視圖範圍bean?「*可能是相關的。 – Lii

回答

1

當您使用JSTL標籤(如<c:if>,)時,視圖範圍的bean將在來自/到同一視圖的每個請求中重新創建等等,或者當您使用binding屬性將JSF組件綁定爲視圖範圍的bean的屬性時。這顯然是在你的複合組件中發生了什麼。

您需要重寫您的複合組件,使其不使用任何JSTL標籤。結合一些JSF組件作爲bean的屬性,也可避免在許多方面,但如果這是真的無法避免,則禁用部分狀態web.xml節約應該在大多數的情況下工作:

<context-param> 
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> 
    <param-value>false</param-value> 
</context-param> 

如果這對你不起作用,那麼你真的必須與我們分享你的複合組件實現代碼,這樣我們才能指出注意事項並提出正確的方法。

+1

我更新了我的答案。我沒有使用JSTL。看起來同一個bean在同一視圖中共享,但我不明白爲什麼構造函數會被調用。 – Sydney

+0

JSF impl/version究竟是什麼?你嘗試禁用部分狀態保存嗎? – BalusC

+0

我試圖禁用部分狀態保存。信息:初始化Mojarra 2.1.0(FCS 20110303)。對於''ViewingScope' bean,構造函數在顯示視圖時只應調用一次,是嗎? – Sydney