`

JSF 生命周期总结

    博客分类:
  • JSF
阅读更多
当一个http 请求来临的时候,
首先会调用FacesServlet的service来处理。
现假设这个请求是第一次请求:
1。执行该生命周期整个阶段的execute方法。//处理除了渲染视图外的所有事情(执行生命周期前五个阶段的事情)。
    第一次请求,这里基本不做什么事情。
    若是第二次请求。则execute则可能完整的走完其生命周期的六个阶段
    这六个生命周期分别由六个Phase来实现
    1)RestoreViewPhase
    2)ApplyRequestValuesPhase
    3)ProcessValidationsPhase
    4)UpdateModelValuesPhase
    5)InvokeApplicationPhase
    6)RenderResponsePhase
    1.1RestoreViewPhase.doPhase()当中调用initView()来初始化原来的视图
        1.1.1 RestoreViewPhase.execute()执行恢复视图的实际事情
        1.1.2 ViewHandler.restoreView()
        1.1.2.1 UIViewRoot.processRestoreState(见如下)
    1.2ApplyRequestValuesPhase.doPhase()
        1.2.1调用ApplyRequestValuesPhase.execute();
        1.2.2UIViewRoot.processDecodes()进行相应的解码工作。然后依次调用其子节点。
        1.2.2.1调用每个组件的decode()方法。
    1.3ProcessValidationsPhase.doPhase()
        1.3.1调用ApplyRequestValuesPhase.execute()
        1.3.2UIViewRoot.processValidators()
    1.4UpdateModelValuesPhase.doPhase()
        1.4.1调用ApplyRequestValuesPhase.execute()
        1.4.2UIViewRoot.processUpdates()
    1.5InvokeApplicationPhase.doPhase()
        1.5.1调用ApplyRequestValuesPhase.execute()
        1.5.2UIViewRoot.processApplication()
        1.5.3UIViewRoot.broadcastEvents()
            1.5.3.1processEvents();
            1.5.3.1.1 broadcast
2。执行该生命周期的render方法。
    2.1。在该方法中调用facesContext.getApplication().getViewHandler().
                 renderView(facesContext, facesContext.getViewRoot());方法从组件树的根开始渲染。
      2.1.1。在这个ViewHandler里有一个方法是buildView创建相应的视图。。。
            该组件的所有属性也是在这个时候设置的.包括一些通过EL表达式与BackBean绑定的属性,只不过此时并不把BackBean的数据直接存储在这个Compoment里.
            而是存放其相应的表达式,待需要的时候再去取.
        2.1.2。然后再调用encodeAll方法,渲染组件树.
            参见如下:
        2.1.3。StateManager.saveSerializedView(context)来保存视图的状态。
            UIViewRoot.processSaveState(context)从树根开始保存视图状态。
            2.1.3.1 然后调用该组件的saveState方法(只有当实现了StateHolder接口才该用该方法)
                This interface is implemented by classes that need to save their state between requests
   




生命周期五个阶段。
1。创建或恢复视图//构成一个组件树。
2。应用请求值//把页面上传过来的值赋给相应的组件。这个值一般都是简单类型的。如String等字符串。从调用UIViewRoot的processDecodes方法开始,依次递归
3。处理验证。对在第二阶段形成的组件树。应用转换器与验证器进行验证。从调用UIViewRoot的processValidators方法开始
4。更新模型值。对于在第三阶段验证过的组件树。把组件树的数据绑定到后台的托管 Bean中去。依次从UIViewRoot 调用processUpdates
5。调用应用程序,更新完后台BackBean的数据以后,对于需要触发事件的组件,调用相应的方法,还是调用UIViewRoot的processApplication方法
6。渲染响应。
新增属性设置时间:

在HeadResourceRender中渲染HtmlSimpleTogglePanel的头.

调用先后顺序,
compoment(默认)
encodeAll
    -encodeBegin
        -render.encodeBegin(下面两个方法richfaces专用)
            -render.preEncodeBegin(可重写)
            -render.doEncodeBegin(可重写)
    -encodeChildren
        -render.encodeChildren
            -render.preEncodeBegin(可重写)
            -render.doEncodeChildren
                -render.renderChildren
    -encodeEnd
        -render.encodeEnd
            -render.doEncodeEnd
            
因此我们写自己的组件,必须重写encodeBegin 并且调用该组件想要做的事情,
然后再调用super.encodeBegin()方法.
对于PFHtmlTableGrid来说,我们主要覆写其encodeBegin方法。

processRestoreState(UIViewRoot):
    -restoreState
    -循环遍历所有的孩子节点,恢复视图
    -孩子节点.processRestoreState
    
    
processDecodes(UIViewRoot)
    -AjaxContextImpl.invokeOnRegionOrRoot()
        -processDecodes()
            -decode()方法
            
            
象PFHtmlTableGrid的processUpdates就是调用UIDataAdapter的方法。
    
总结:
    对于PFHtmlTableGrid组件来说,它的执行流程如下:
    1。若是第一次请求,jsf需要创建一个全新的组件树。
        1.1先调用PFHtmlTableGrid.encodeBegin()
        1.2然后再调用PFHtmlTableGrid.encodeEnd();
        1.3视图渲染完以后,要保存视图的状态,调用PFHtmlTableGrid.saveState();
    2.若是第二次请求。jsf则不用创建一个全新的组件树,而是恢复在FacesContext中的相应组件树。
        2.1先调用PFHtmlTableGrid.restoreState()//恢复视图阶段
        2.2调用PFHtmlTableGrid.decode()//应用请求值阶段
        2.3调用PFHtmlTableGrid.processValidates()(如果有的话)//处理验证,一般不用重写。
        2.4调用PFHtmlTableGrid.processUpdates()(如果有的话)//处理验证,一般不用重写。
        2.5调用PFHtmlTableGrid.broadcast(如果有的话)//处理验证,一般不用重写。
        2.6返回渲染视图
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics