本系列最後一篇,示範如何將 Spring Framework 整合至現有 JSF 應用程式(開發人員論壇註冊範例),利用 Spring 的依賴注入(DI)與 Bean 管理能力,增強應用程式的模組化與可測試性。

專案結構包含:web.xml、faces-config.xml、geronimo-web.xml、signup.jsp、SignupData.java(Managed Bean)。JSF 由 Apache MyFaces 實現,搭配 Tomahawk 元件庫。
關鍵設定檔片段:
<!-- faces-config.xml -->
<managed-bean>
<managed-bean-name>signupData</managed-bean-name>
<managed-bean-class>devSignup.SignupData</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<navigation-rule>...</navigation-rule>

spring.jar(含所有模組)或依需求挑選模組化 JAR(core、beans、context、web、aop 等)。

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
啟動 Spring 根 WebApplicationContext,載入 applicationContext.xml 定義的 Bean。
<application>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
DelegatingVariableResolver 優先解析 Spring Bean,失敗再委派給 JSF 預設解析器,實現 JSF 與 Spring Bean 互通。
於 signupData 定義新增 managed-property:
<managed-property>
<property-name>hash</property-name>
<value>#{genHash.hash}</value> <!-- 參照 Spring Bean genHash 的 hash 屬性 -->
</managed-property>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "https://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="signupData" class="devSignup.SignupData" lazy-init="true"/>
<bean id="genHash" class="devSignup.HashGenerator" lazy-init="true"/>
</beans>
lazy-init="true" 表示 Bean 於首次使用時才建立。
private String _hash = null;
public String getHash() { return _hash; }
public void setHash(String h) { _hash = h; }
package devSignup;
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;
public class HashGenerator {
public void setHash(String h) { /* 唯讀 Bean,忽略設定 */ }
public String getHash() {
ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
try {
SignupData bean = (SignupData) ctx.getBean("signupData");
return Integer.toString(bean.getScreenName().hashCode());
} catch (NoSuchBeanDefinitionException e) { return "no-data-bean"; }
catch (javax.faces.FacesException e) { return "no-screen-name"; }
}
}
HashGenerator 透過 Spring ApplicationContext 取得 JSF Managed Bean signupData,計算其 screenName 雜湊值。展示 Spring Bean 可存取 JSF Bean、反之亦然的雙向整合。
<p>
Your application was successful, ${signupData.screenName}, welcome to our forums!<br>
Your hash is ${signupData.hash}.
</p>
devSignup.war。https://localhost:8080/console/,預設 server/manager)卸載舊版 → Deploy New 上傳新 WAR。https://localhost:8080/devSignup/signup.faces,填寫表單送出,成功頁將顯示個人化歡迎訊息與 Spring Bean 計算的雜湊值。

本教程示範了將 Spring Framework 整合至 JSF 應用程式的完整步驟:註冊 ContextLoaderListener、設定 DelegatingVariableResolver、定義 Spring Bean、於 JSF Managed Bean 注入 Spring Bean、編寫 Spring Bean 存取 JSF Bean。透過此整合,開發者可利用 Spring 的 DI、AOP、交易管理、ORM 整合等企業級功能,構建更健壯、可維護的 Java EE 應用程式。本系列五篇教程涵蓋 MyFaces、Tomahawk、ajax4jsf、Trinidad、Spring 五大技術整合,為 JSF on Geronimo 開發提供完整實戰指引。