其他 Web 框架

本章详细介绍了 Spring 与第三方 Web 框架的集成。

Spring 框架的核心价值主张之一是赋予选择的权利。从广义上讲,Spring 不会强迫您使用或购买任何特定的架构、技术或方法论(尽管它确实推荐某些方法)。这种自由选择最适合开发人员及其开发团队的架构、技术或方法论的自由,在 Web 领域最为明显,Spring 提供了自己的 Web 框架(Spring MVCSpring 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 属性的名称。它的 getWebApplicationContext() 方法在 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 键下不存在对象时返回 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 使用的标准统一 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

当将您的属性映射到 faces-config.xml 中的 Bean 时,自定义 ELResolver 工作良好,但有时您可能需要显式地获取 Bean。 FacesContextUtils 类使这变得容易。它类似于 WebApplicationContextUtils,只是它接受 FacesContext 参数而不是 ServletContext 参数。

以下示例演示了如何使用 FacesContextUtils

ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

Apache Struts

由 Craig McClanahan 发明,Struts 是一个由 Apache 软件基金会托管的开源项目。Struts 1.x 极大地简化了 JSP/Servlet 编程范式,并赢得了许多使用专有框架的开发人员。它简化了编程模型;它是开源的;它拥有庞大的社区,这使得该项目得以发展壮大,并在 Java Web 开发人员中流行起来。

作为原始 Struts 1.x 的继任者,请查看 Struts 2.x 或更新版本,以及 Struts 提供的 Spring 插件,用于内置的 Spring 集成。

Apache Tapestry

Tapestry 是一个“面向组件的框架,用于在 Java 中创建动态、健壮、高度可扩展的 Web 应用程序”。

虽然 Spring 有自己的 强大的 Web 层,但使用 Tapestry 构建 Web 用户界面和使用 Spring 容器构建底层,可以为构建企业 Java 应用程序带来许多独特的优势。

有关更多信息,请参阅 Tapestry 的专用 Spring 集成模块

更多资源

以下链接指向本章中描述的各种 Web 框架的更多资源。