|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
其他 Web 框架
本章详细介绍了 Spring 与第三方 Web 框架的集成。
Spring 框架的核心价值主张之一就是赋予开发者选择权。总体而言,Spring 并不会强制你使用或绑定任何特定的架构、技术或方法论(尽管它确实会推荐某些方案优于其他方案)。这种自由选择最适合开发者及其开发团队的架构、技术或方法论的特性,在 Web 领域表现得尤为明显:Spring 不仅提供了自己的 Web 框架(Spring MVC 和 Spring WebFlux),同时还支持与多个流行的第三方 Web 框架进行集成。
通用配置
在深入探讨每个受支持的 Web 框架的具体集成细节之前,我们先来看一下与任何特定 Web 框架无关的通用 Spring 配置。(本节同样适用于 Spring 自身的各种 Web 框架变体。)
Spring 轻量级应用模型所倡导的概念之一(姑且用这个词)就是分层架构。请记住,在“经典”的分层架构中,Web 层只是众多层次中的一个。它作为服务端应用程序的入口点之一,会委托给在服务层中定义的服务对象(外观类),以满足特定业务需求(且与表现层技术无关)的用例。在 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 之上的,因此你可以使用以下代码片段来访问由 ApplicationContext 创建的这个“业务上下文”ContextLoaderListener。
以下示例展示了如何获取 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 所使用的标准 Unified EL 集成。它首先委托给
Spring 的“业务上下文”WebApplicationContext,然后再委托给底层 JSF 实现的默认解析器。
在配置方面,您可以在 JSF 的 SpringBeanFacesELResolver 文件中定义 faces-context.xml,如下例所示:
<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());