其他 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
属性的名称。它的 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 Tapestry
Tapestry 是一个“面向组件的框架,用于在 Java 中创建动态、健壮、高度可扩展的 Web 应用程序”。
虽然 Spring 有自己的 强大的 Web 层,但使用 Tapestry 构建 Web 用户界面和使用 Spring 容器构建底层,可以为构建企业 Java 应用程序带来许多独特的优势。
有关更多信息,请参阅 Tapestry 的专用 Spring 集成模块。