其他 Web 框架
本章詳細介紹了 Spring 與第三方 Web 框架的整合。
Spring 框架的核心價值主張之一是實現選擇。通常來說,Spring 不強制你使用或接受任何特定的架構、技術或方法(儘管它肯定會推薦一些)。這種選擇最適合開發人員及其開發團隊的架構、技術或方法的自由,在 Web 領域表現得最為明顯,Spring 提供了自己的 Web 框架(Spring MVC 和 Spring WebFlux),同時還支援與一些流行的第三方 Web 框架整合。
通用配置
在深入研究每個受支援的 Web 框架的整合細節之前,讓我們首先看一下不特定於任何一個 Web 框架的通用 Spring 配置。(本節同樣適用於 Spring 自己的 Web 框架變體。)
Spring 輕量級應用程式模型所倡導的(由於缺乏更好的詞語)概念之一是分層架構。請記住,在“經典”分層架構中,Web 層只是眾多層中的一層。它充當伺服器端應用程式的入口點之一,並將業務委託給服務層中定義的(門面)服務物件,以滿足業務特定(與表示技術無關)的用例。在 Spring 中,這些服務物件、任何其他業務特定物件、資料訪問物件以及其他物件存在於一個獨特的“業務上下文”中,該上下文不包含任何 Web 或表示層物件(表示物件,例如 Spring MVC 控制器,通常在獨特的“表示上下文”中配置)。本節詳細介紹瞭如何配置一個包含應用程式中所有“業務 bean”的 Spring 容器(一個 WebApplicationContext)。
具體來說,您只需在 Web 應用程式的標準 Jakarta EE Servlet web.xml 檔案中宣告一個 ContextLoaderListener,並新增一個 contextConfigLocation <context-param/> 部分(在同一個檔案中),該部分定義要載入的 Spring XML 配置檔案集。
考慮以下 <listener/> 配置
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
進一步考慮以下 <context-param/> 配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
如果您不指定 contextConfigLocation 上下文引數,ContextLoaderListener 將查詢名為 /WEB-INF/applicationContext.xml 的檔案進行載入。一旦上下文檔案載入完畢,Spring 將根據 bean 定義建立一個 WebApplicationContext 物件,並將其儲存在 Web 應用程式的 ServletContext 中。
所有 Java Web 框架都構建在 Servlet API 之上,因此您可以使用以下程式碼片段來訪問由 ContextLoaderListener 建立的這個“業務上下文” ApplicationContext。
以下示例展示瞭如何獲取 WebApplicationContext
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
WebApplicationContextUtils 類是為了方便而設計的,因此您無需記住 ServletContext 屬性的名稱。如果 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 鍵下不存在物件,其 getWebApplicationContext() 方法將返回 null。為了避免應用程式中出現 NullPointerExceptions,最好使用 getRequiredWebApplicationContext() 方法。當 ApplicationContext 缺失時,此方法會丟擲異常。
一旦您獲得了 WebApplicationContext 的引用,就可以透過其名稱或型別檢索 bean。大多數開發人員透過名稱檢索 bean,然後將其轉換為其實現介面之一。
幸運的是,本節中的大多數框架都有更簡單的查詢 bean 的方法。它們不僅使從 Spring 容器獲取 bean 變得容易,而且還允許您在控制器上使用依賴注入。每個 Web 框架部分都有關於其特定整合策略的更多詳細資訊。
JSF
JavaServer Faces (JSF) 是 JCP 的標準組件化、事件驅動的 Web 使用者介面框架。它是 Jakarta EE 傘形專案的一個官方組成部分,也可以單獨使用,例如透過在 Tomcat 中嵌入 Mojarra 或 MyFaces。
請注意,JSF 的最新版本與應用伺服器中的 CDI 基礎設施緊密相關,一些新的 JSF 功能僅在這種環境下才能工作。Spring 的 JSF 支援已不再積極發展,主要用於在現代化舊版 JSF 應用程式時的遷移目的。
Spring 的 JSF 整合的關鍵要素是 JSF ELResolver 機制。
Spring Bean 解析器
SpringBeanFacesELResolver 是一個 JSF 相容的 ELResolver 實現,它與 JSF 和 JSP 中使用的標準 Unified EL 整合。它首先委託給 Spring 的“業務上下文” WebApplicationContext,然後委託給底層 JSF 實現的預設解析器。
在配置方面,您可以在 JSF 的 faces-context.xml 檔案中定義 SpringBeanFacesELResolver,示例如下:
<faces-config>
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
...
</application>
</faces-config>
使用 FacesContextUtils
自定義 ELResolver 在將屬性對映到 faces-config.xml 中的 bean 時效果很好,但有時您可能需要顯式獲取一個 bean。FacesContextUtils 類使這變得容易。它類似於 WebApplicationContextUtils,只是它接受一個 FacesContext 引數而不是 ServletContext 引數。
以下示例展示瞭如何使用 FacesContextUtils
ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
Apache Tapestry
Tapestry 是一個“元件導向的框架,用於在 Java 中建立動態、健壯、高度可擴充套件的 Web 應用程式。”
雖然 Spring 有自己的強大的 Web 層,但將 Tapestry 用於 Web 使用者介面和 Spring 容器用於下層結合構建企業 Java 應用程式具有許多獨特的優勢。
有關更多資訊,請參閱 Tapestry 專用的Spring 整合模組。