当一个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返回渲染视图
首先会调用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返回渲染视图