前文已述:FacesServlet.init() 建立兩大核心物件——FacesContextFactory(請求包裝工廠)與 Lifecycle(階段處理鏈,類比 Filter Chain)。
public void service(ServletRequest req, ServletResponse resp) {
// 1. 包裝請求為 FacesContext
FacesContext ctx = facesContextFactory.getFacesContext(
servletConfig.getServletContext(), req, resp, lifecycle);
// 2. 執行階段鏈(邏輯處理)
lifecycle.execute(ctx);
// 3. 渲染回應階段
lifecycle.render(ctx);
}
FacesContextFactoryImpl 實例化 FacesContextImpl,構造參數為 ExternalContextImpl(封裝 Servlet API,實現環境解耦)與 Lifecycle。FacesContextImpl 建構時決定 RenderKitFactory,進而產生針對不同客戶端(瀏覽器、行動裝置)的 RenderKit。ThreadLocal 綁定當前請求的 FacesContext,支援 FacesContext.getCurrentInstance() 隨處取得。LifecycleImpl 內部持有 7 個 Phase 陣列(索引 0 為佔位):
RestoreViewPhase(視圖重建)ApplyRequestValuesPhase(套用請求值)ProcessValidationsPhase(驗證處理)UpdateModelValuesPhase(更新模型值)InvokeApplicationPhase(執行應用邏輯)RenderResponsePhase(呈現回應)execute() 依序執行 Phase 1–5,render() 執行 Phase 6。
// execute() 核心邏輯
for (int i = 1; i < phases.length - 1; i++) {
if (ctx.getRenderResponse() || ctx.getResponseComplete()) break;
phases[i].doPhase(ctx, this, listeners.listIterator());
}
// render() 邏輯
if (!ctx.getResponseComplete()) {
responsePhase.doPhase(ctx, this, listeners.listIterator());
}
關鍵標誌位:
renderResponse:跳過剩餘邏輯階段,直接進入渲染(如驗證失敗)。responseComplete:已完成回應,跳過渲染階段(如重導向、二進位下載)。開發者常用 FacesContext.getCurrentInstance().renderResponse() 或 responseComplete() 控制流程。
doPhase() 接收 PhaseListener 列表,允許在每階段前/後插入自訂邏輯(如效能監控、權限檢查、日誌記錄)。
Phase、LifecycleImpl 屬於 JSF RI (Reference Implementation, com.sun.faces),而 Lifecycle 介面屬 JSF API (javax.faces)。MyFaces 等其他實現可替換內部階段處理邏輯。