弄清楚为什么在我不希望调用它们时调用JSF getter

我正在使用jsf 2 ,我得到了一些我很难解释或理解的行为。

我有几个独立的h:form s。

其中一个看起来像这样:

     Ignore Errors  

我的问题是,无论何时按下前面提到的按钮,我都会看到其他不相关的bean成员getter(也是其他forms的部分)被调用。 (通过记录)

任何getter都没有业务逻辑,但我了解其原因。 通过打印stacktrace我确保JSF确实是调用它们的人。

您如何建议我关注JSF以了解他们被调用的原因? 可能是什么原因?

谢谢! 本。

UPDATE

这是由一个正在运行且不应该运行的getter打印的堆栈跟踪。 正如评论中所讨论的那样,在这个问题中包含所有相关的细节是非常复杂的,所以我宁愿得到帮助我自己找到答案的工具。

 java.lang.Exception at com.aCompanyName.applicationName.beans.aBean.getSomethingFromBean(CurrentDevice.java:382) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at javax.el.BeanELResolver.getValue(BeanELResolver.java:302) at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:175) at org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:142) at com.sun.el.parser.AstValue.getValue(AstValue.java:116) at com.sun.el.parser.AstValue.getValue(AstValue.java:163) at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219) at org.apache.myfaces.view.facelets.el.TagValueExpression.getValue(TagValueExpression.java:85) at org.apache.myfaces.view.facelets.component.UIRepeat.getValue(UIRepeat.java:248) at org.apache.myfaces.view.facelets.component.UIRepeat.getDataModel(UIRepeat.java:211) at org.apache.myfaces.view.facelets.component.UIRepeat._validateAttributes(UIRepeat.java:530) at org.apache.myfaces.view.facelets.component.UIRepeat.visitTree(UIRepeat.java:763) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at javax.faces.component.UIComponent.visitTree(UIComponent.java:797) at javax.faces.component.UIComponentBase.visitTree(UIComponentBase.java:992) at org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener._doTreeVisit(DebugPhaseListener.java:310) at org.apache.myfaces.view.facelets.tag.ui.DebugPhaseListener.afterPhase(DebugPhaseListener.java:286) at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:111) at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:185) at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.openejb.tomcat.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:662) 

更新2

制作SSCCE的工作,一旦有了SSCCE,就会更新。

更新3

使用值属性时似乎会出现此问题。 这是一个SSCCE代码,可以解释这个问题:

   STRING: #{str}        

Bean代码:

 @PostConstruct public void init() { slist.add("Testing"); slist.add("This"); slist.add("Thing"); } private List slist = new ArrayList(); public List getSList(){ logger.trace("Getting LIST"); return slist; } public void doThat(){ logger.trace("DoThat Was Run"); } 

按下按钮时,会输出到日志:

 2011-08-16 16:55:55,853 TRACE [http-80-2] (AdminBean.java:80) - Getting LIST 2011-08-16 16:55:55,865 TRACE [http-80-2] (AdminBean.java:85) - DoThat Was Run 

为什么要运行列表? 这不是多余的吗?

我不使用MyFaces,所以我不会详细说明。 但值得一提的是,在Mojarra上,吸气剂也被称为 。 但是,对于正在发生的事情,堆栈更加清晰。 这是Thread#dumpStack()直到FacesServlet#service() Thread#dumpStack() FacesServlet#service()

 java.lang.Exception: Stack trace at java.lang.Thread.dumpStack(Thread.java:1249) at mypackage.Bean.getList(Bean.java:21) at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at javax.el.BeanELResolver.getValue(BeanELResolver.java:302) at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) at com.sun.el.parser.AstValue.getValue(AstValue.java:116) at com.sun.el.parser.AstValue.getValue(AstValue.java:163) at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219) at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) at com.sun.faces.facelets.component.UIRepeat.getValue(UIRepeat.java:272) at com.sun.faces.facelets.component.UIRepeat.getDataModel(UIRepeat.java:248) at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:442) at com.sun.faces.facelets.component.UIRepeat.doVisitChildren(UIRepeat.java:661) at com.sun.faces.facelets.component.UIRepeat.visitTree(UIRepeat.java:619) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600) at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:240) at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188) at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123) at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:452) at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148) at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303) at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:189) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409) // Remnant omitted for brevity. 

因此,在状态管理需要访问整个组件树的恢复视图阶段期间发生这种情况。 UIRepeat反过来需要在访问其子项时设置行索引。

根据UIRepeat#doVisitChildren()源,行索引设置为-1 。 最终目标是只访问树中的子项,而不是迭代模型值,也不渲染任何东西。 它只需要DataModel就可以设置行索引。 datamodel的值是您正在看到调用getter的列表。 如果一切正常,则在恢复视图阶段只应调用此getter一次。 但是,如果在例如渲染响应阶段期间调用它,那么您可能会担心这一点,因为它完全没必要。