其他 Web 框架
本章详细介绍了 Spring 与第三方 Web 框架的集成。
Spring Framework 的核心价值主张之一是提供选择。从广义上讲,Spring 不强迫您使用或接受任何特定的架构、技术或方法(尽管它肯定会推荐一些优于其他的)。这种自由选择对开发者及其开发团队最相关的架构、技术或方法的自由,在 Web 领域尤为明显,Spring 在提供自己的 Web 框架(Spring MVC 和 Spring 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 集成模块。