Other Web Frameworks
本章详细介绍了 Spring 与第三方 Web 框架的集成。
This chapter details Spring’s integration with third-party web frameworks.
Spring Framework 的核心价值主张之一就是支持_choice_。一般来说,Spring 不会强制你使用或购买任何特定的架构、技术或方法(尽管它肯定会建议使用一些替代其他一些)。在 Web 领域,这种选择和选择与开发人员及其开发团队最相关的架构、技术或方法的自由尤其明显,Spring 在该领域提供了自己的 Web 框架(Spring MVC和Spring WebFlux),同时还支持与许多流行的第三方 Web 框架集成。
One of the core value propositions of the Spring Framework is that of enabling choice. In a general sense, Spring does not force you to use or buy into any particular architecture, technology, or methodology (although it certainly recommends some over others). This freedom to pick and choose the architecture, technology, or methodology that is most relevant to a developer and their development team is arguably most evident in the web area, where Spring provides its own web frameworks (Spring MVC and Spring WebFlux) while, at the same time, supporting integration with a number of popular third-party web frameworks.
Common Configuration
在深入探讨各个支持的 Web 框架的具体集成之前,让我们先了解一下不特定于任何 Web 框架的常见的 Spring 配置。(本节同样适用于 Spring 自己 Web 框架的变体。)
Before diving into the integration specifics of each supported web framework, let us first take a look at common Spring configuration that is not specific to any one web framework. (This section is equally applicable to Spring’s own web framework variants.)
Spring 的轻量级应用模型提倡的一个概念(因缺乏更好的词而用)是一个分层架构。请记住,在一个“经典的”分层架构中,Web 层只是众多层中的一层。它充当进入服务器端应用的入口点之一,并将任务委托给服务层中定义的服务对象(门面),来满足特定于业务(并且与表示技术无关)的用例。在 Spring 中,这些服务对象、其他特定于业务的对象、数据访问对象等都存在于一个不同的“业务上下文”中,该上下文不包含任何 Web 或表示层对象(表示对象,例如 Spring MVC 控制器,通常配置在不同的“表示上下文”中)。本节详细介绍了如何配置 Spring 容器(一个 WebApplicationContext
),该容器包含您应用中的所有“业务 bean”。
One of the concepts (for want of a better word) espoused by Spring’s lightweight
application model is that of a layered architecture. Remember that in a "classic"
layered architecture, the web layer is but one of many layers. It serves as one of the
entry points into a server-side application, and it delegates to service objects
(facades) that are defined in a service layer to satisfy business-specific (and
presentation-technology agnostic) use cases. In Spring, these service objects, any other
business-specific objects, data-access objects, and others exist in a distinct "business
context", which contains no web or presentation layer objects (presentation objects,
such as Spring MVC controllers, are typically configured in a distinct "presentation
context"). This section details how you can configure a Spring container (a
WebApplicationContext
) that contains all of the 'business beans' in your application.
进入具体问题,您需要做的就是声明一个https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/ContextLoaderListener.html[ContextLoaderListener
]在 Web 应用程序的标准 Jakarta EE servlet web.xml
文件中,并添加一个 contextConfigLocation
<context-param/>
部分(在同一文件中),用于定义要加载哪组 Spring XML 配置文件。
Moving on to specifics, all you need to do is declare a
ContextLoaderListener
in the standard Jakarta EE servlet web.xml
file of your web application and add a
contextConfigLocation
<context-param/>
section (in the same file) that defines which
set of Spring XML configuration files to load.
考虑以下 <listener/>
配置:
Consider the following <listener/>
configuration:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
进一步考虑以下 <context-param/>
配置:
Further consider the following <context-param/>
configuration:
<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 定义创建一个https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/WebApplicationContext.html[WebApplicationContext
]对象,并将其存储在 Web 应用程序的 ServletContext
中。
If you do not specify the contextConfigLocation
context parameter, the
ContextLoaderListener
looks for a file called /WEB-INF/applicationContext.xml
to
load. Once the context files are loaded, Spring creates a
WebApplicationContext
object based on the bean definitions and stores it in the ServletContext
of the web
application.
所有 Java Web 框架都构建在 Servlet API 之上,所以您可以使用以下代码片段,获得 ContextLoaderListener
创建的“业务上下文”ApplicationContext
的访问权限。
All Java web frameworks are built on top of the Servlet API, so you can use the
following code snippet to get access to this "business context" ApplicationContext
created by the ContextLoaderListener
.
以下示例展示如何获取 WebApplicationContext
:
The following example shows how to get the WebApplicationContext
:
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
{"spring-framework-api"/web/context/support/WebApplicationContextUtils.html[WebApplicationContextUtils
] 类是为方便所设计的,因此您不必记住 [ServletContext
] 属性的名称。它的 [getWebApplicationContext()
] 方法将在 [WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
] 键下找不到对象时返回 [null
]。与其冒险在您的应用程序中获取 [NullPointerExceptions
],不如使用 [getRequiredWebApplicationContext()
] 方法。当 [ApplicationContext
] 缺失时,此方法会抛出异常。
The
WebApplicationContextUtils
class is for convenience, so you need not remember the name of the ServletContext
attribute. Its getWebApplicationContext()
method returns null
if an object
does not exist under the WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
key. Rather than risk getting NullPointerExceptions
in your application, it is better
to use the getRequiredWebApplicationContext()
method. This method throws an exception
when the ApplicationContext
is missing.
一旦获得对 WebApplicationContext
的引用,就可以按名称或类型检索 bean。大多数开发人员按名称检索 bean,然后将它们强制转换为其实现的接口之一。
Once you have a reference to the WebApplicationContext
, you can retrieve beans by their
name or type. Most developers retrieve beans by name and then cast them to one of their
implemented interfaces.
幸运的是,本节中大多数框架都有更简单的查找 bean 的方法。它们不仅可以轻松地从 Spring 容器中获取 bean,还可以让您对其控制器使用依赖项注入。每个 Web 框架的部分都更详细地介绍了其特定的集成策略。
Fortunately, most of the frameworks in this section have simpler ways of looking up beans. Not only do they make it easy to get beans from a Spring container, but they also let you use dependency injection on their controllers. Each web framework section has more detail on its specific integration strategies.
JSF
JavaServer Faces (JSF) 是 JCP 的基于组件、事件驱动的 Web 用户界面框架的标准。它是 Jakarta EE 框架的正式部分,但也可以单独使用,例如通过在 Tomcat 中嵌入 Mojarra 或 MyFaces。
JavaServer Faces (JSF) is the JCP’s standard component-based, event-driven web user interface framework. It is an official part of the Jakarta EE umbrella but also individually usable, e.g. through embedding Mojarra or MyFaces within Tomcat.
请注意,最近版本的 JSF 与应用程序服务器中的 CDI 基础设施紧密相连,一些新的 JSF 功能仅在这样的环境中才起作用。Spring 的 JSF 支持不再积极发展,主要是出于在对基于 JSF 的较旧应用程序进行现代化改造时的迁移目的。
Please note that recent versions of JSF became closely tied to CDI infrastructure in application servers, with some new JSF functionality only working in such an environment. Spring’s JSF support is not actively evolved anymore and primarily exists for migration purposes when modernizing older JSF-based applications.
Spring 的 JSF 集成中的关键元素是 JSF ELResolver
机制。
The key element in Spring’s JSF integration is the JSF ELResolver
mechanism.
Spring Bean Resolver
SpringBeanFacesELResolver
是一个兼容 JSF 的 ELResolver
实现,它与 JSF 和 JSP 使用的标准统一 EL 集成在一起。它首先委托给 Spring 的“业务上下文” WebApplicationContext
,然后委托给底层 JSF 实现的默认解析器。
SpringBeanFacesELResolver
is a JSF compliant ELResolver
implementation,
integrating with the standard Unified EL as used by JSF and JSP. It delegates to
Spring’s "business context" WebApplicationContext
first and then to the
default resolver of the underlying JSF implementation.
关于配置,你可以在 JSF faces-context.xml
文件中定义 SpringBeanFacesELResolver
,如下例所示:
Configuration-wise, you can define SpringBeanFacesELResolver
in your JSF
faces-context.xml
file, as the following example shows:
<faces-config>
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
...
</application>
</faces-config>
Using FacesContextUtils
在将您的属性映射到 [faces-config.xml
] 中的 bean 时,自定义 [ELResolver
] 可以很好地工作,但是,有时您可能需要明确获取 bean。FacesContextUtils
类可以轻松地做到这一点。它类似于 [WebApplicationContextUtils
],不同之处在于它接受一个 [FacesContext
] 参数,而不是 [ServletContext
] 参数。
A custom ELResolver
works well when mapping your properties to beans in
faces-config.xml
, but, at times, you may need to explicitly grab a bean.
The FacesContextUtils
class makes this easy. It is similar to WebApplicationContextUtils
, except that
it takes a FacesContext
parameter rather than a ServletContext
parameter.
以下示例显示了如何使用 FacesContextUtils
:
The following example shows how to use FacesContextUtils
:
ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
Apache Struts
Struts由 Craig McClanahan 发明,是一个由 Apache Software Foundation 托管的开源项目。Struts 1.x 极大地简化了 JSP/Servlet 编程范例,赢得了许多使用专有框架的开发人员的青睐。它简化了编程模型,具有开源属性,并且拥有一个庞大的社区,这让该项目得以成长并受到 Java Web 开发人员的欢迎。
Invented by Craig McClanahan, Struts is an open-source project hosted by the Apache Software Foundation. Struts 1.x greatly simplified the JSP/Servlet programming paradigm and won over many developers who were using proprietary frameworks. It simplified the programming model; it was open source; and it had a large community, which let the project grow and become popular among Java web developers.
作为原版 Struts 1.x 的继任者,查看 Struts 2.x 或更新版本以及 Struts 提供的 Spring Plugin,以实现内置的 Spring 集成。
As a successor to the original Struts 1.x, check out Struts 2.x or more recent versions as well as the Struts-provided Spring Plugin for built-in Spring integration.
Apache Tapestry
Tapestry是“面向组件的框架,用于在 Java 中创建动态、健壮、高度可扩展的 web 应用程序”。
Tapestry is a "Component oriented framework for creating dynamic, robust, highly scalable web applications in Java."
虽然 Spring 有自己的 powerful web layer,但通过结合 Tapestry(用于 Web 用户界面)和 Spring 容器(用于较低层级)来构建企业 Java 应用程序,可具有许多独一无二的优势。
While Spring has its own powerful web layer, there are a number of unique advantages to building an enterprise Java application by using a combination of Tapestry for the web user interface and the Spring container for the lower layers.
如需了解更多信息,请参阅 Tapestry 的专用 integration module for Spring。
For more information, see Tapestry’s dedicated integration module for Spring.