其他 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
属性的名称。
如果 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
键下不存在对象,它的 getWebApplicationContext()
方法将返回 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 集成模块。