我的问题是我的ViewScoped
bean之一在同一视图中多次创建。每次我在树中选择一个节点时,都会创建ViewScopedBean
的构造函数。
<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>
使用的所有bean都设置为@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 xxx.bean.ViewScopedBean@4e1d2b8e
点击树上的两次:
Constructor of ViewScopedBean xxx.bean.ViewScopedBean@4eb64f2e
Constructor of ViewScopedBean xxx.bean.ViewScopedBean@66863941
然后我打开调试窗口<ui:debug/>
,viewScopedBean
设置为xxx.bean.ViewScopedBean@4e1d2b8e
答案 0 :(得分:1)
当您在视图中使用JSTL标记(如<c:if>
,<c:forEach>
等)或绑定JSF时,将在来自/向同一视图的每个请求上重新创建视图范围bean使用binding
属性将component作为视图作用域bean的属性。这显然是复合材料组件中发生的事情。
您需要重写复合组件,使其不使用任何JSTL标记。将一些JSF组件绑定为bean的属性也可以通过多种方式避免,但如果真的无法避免,那么在web.xml
中禁用部分状态保存应该适用于大多数情况:
<context-param>
<param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
<param-value>false</param-value>
</context-param>
如果这对您不起作用,那么您真的必须与我们分享您的复合组件实现代码,以便我们指出警告并提出正确的方法。