其他 Web 框架

本章詳細介紹了 Spring 與第三方 Web 框架的整合。

Spring Framework 的核心價值主張之一是提供選擇。從廣義上講,Spring 不強迫您使用或接受任何特定的架構、技術或方法(儘管它肯定會推薦一些優於其他的)。這種自由選擇對開發者及其開發團隊最相關的架構、技術或方法的自由,在 Web 領域尤為明顯,Spring 在提供自己的 Web 框架(Spring MVCSpring WebFlux)的同時,也支援與許多流行的第三方 Web 框架整合。

通用配置

在深入探討每個受支援的 Web 框架的整合細節之前,讓我們先看看不特定於任何一個 Web 框架的通用 Spring 配置。(本節同樣適用於 Spring 自身的 Web 框架變體。)

Spring 輕量級應用模型所倡導的概念之一(姑且如此稱呼)是分層架構。請記住,在“經典”的分層架構中,Web 層僅僅是眾多層中的一個。它充當伺服器端應用的入口點之一,並將業務特定(且與展示技術無關)的用例委託給服務層中定義的服務物件(facades)。在 Spring 中,這些服務物件、任何其他業務特定物件、資料訪問物件等存在於一個獨立的“業務上下文”中,該上下文不包含 Web 或展示層物件(展示物件,如 Spring MVC 控制器,通常配置在獨立的“展示上下文”中)。本節詳細介紹瞭如何配置一個 Spring 容器(一個 `WebApplicationContext`),其中包含應用程式中的所有“業務 Bean”。

具體來說,您只需在 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 屬性的名稱。它的 getWebApplicationContext() 方法如果在 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 鍵下不存在物件,則返回 null。與其冒險在應用程式中出現 NullPointerException,不如使用 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 Struts

Struts 由 Craig McClanahan 發明,是 Apache Software Foundation 託管的一個開源專案。Struts 1.x 極大地簡化了 JSP/Servlet 程式設計範例,贏得了許多使用專有框架的開發人員的青睞。它簡化了程式設計模型;它是開源的;並且擁有龐大的社群,這使得該專案得以發展並在 Java Web 開發人員中流行起來。

作為原始 Struts 1.x 的後續版本,請檢視 Struts 2.x 或更高版本,以及 Struts 提供的 Spring Plugin 以獲取內建的 Spring 整合。

Apache Tapestry

Tapestry 是一個“面向元件的框架,用於在 Java 中建立動態、健壯、高度可伸縮的 Web 應用程式。”

雖然 Spring 有自己的強大的 Web 層,但透過結合使用 Tapestry 作為 Web 使用者介面和 Spring 容器作為下層來構建企業級 Java 應用,存在一些獨特的優勢。

欲瞭解更多資訊,請參閱 Tapestry 專用的Spring 整合模組

更多資源

以下連結指向本章中描述的各種 Web 框架的更多資源。