Spring Web Flow 2.0 M2 刚刚发布了。我对此版本感到特别兴奋,因为它为实现我们社区未来的宏大愿景奠定了所需的基础。在这篇文章中,我将解释这个愿景是什么,以及这个基础将具体实现什么。我还会详细介绍 Web Flow 2.0 的架构,并将其与 1.0 版本进行比较。
Spring Web Flow 2.0 愿景
2.0 的目标是将 Spring Web Flow 演进为一个受控导航引擎,以显著改进对 JavaServerFaces、流程管理的持久化以及异步事件处理(Ajax)的原生支持。新的 Spring Faces 项目将基于 Web Flow 2.0,在 Spring 环境中为 JSF 视图提供一流支持。此外,Web Flow 将继续为基于 Spring MVC 的视图提供一流支持,允许原生 JSF 和 MVC 视图充分发挥作用,甚至在同一应用程序中同时使用。
* 更新:上述愿景已于 08 年 1 月 11 日根据自 2007 年 Spring Experience 以来收到的 Spring 社区大量反馈进行了更新。基于这些反馈,计划于 2008 年 3 月发布的 Spring Web Flow 2.0 将继续专注于 Web 应用程序中受控导航和应用程序事务的编排,可作为基于动作的 MVC 环境中 Spring MVC 的补充,以及基于组件的环境中 JavaServerFaces 的补充。与 JSF 一起使用时,Spring Web Flow 2.0 可以作为“黑盒”驱动整个基于 JSF 的 Web 应用程序,或者可以与实现自由导航要求的标准 JSF 导航处理器混合使用。 2.0,因此,将是一个演进版本,增加对 JSF 和 Ajax 的一流支持,支持 Java 1.4+,并提供与 SWF 1.0 流程定义语言的完全向后兼容。
现在我想更详细地介绍一下 Web Flow 2.0 引擎架构,以及它与 1.0 版本的比较。首先让我们回顾一下 1.0 的历史。
1.0 历史回顾...
在 Spring Web Flow 1.0 中,SWF 控制器引擎负责 Web 请求生命周期的一半;与请求处理相关的部分,通常称为
动作阶段。另一半,
渲染阶段,则交由调用者负责:Spring MVC、Struts 或 JSF 前端控制器。这可以在下面的 SWF 1.0 架构图中显示。

这种架构的主要好处是,将 Spring Web Flow 引入现有项目变得非常自然。无论您使用的是 Struts、Spring MVC 还是 JSF,您都可以引入 Web Flow 来处理更复杂的用户交互,其余部分则使用普通控制器。
这种方法的缺点是,在请求生命周期的视图渲染阶段,如果不依赖于前端控制器特定的适配器,很难应用应用程序控制逻辑。例如,考虑一下对流程管理的持久化上下文的需求。这样的上下文应该在一个新的流程执行开始时分配,在结束时释放,并在中间视图渲染后断开连接,等待用户继续。如果视图渲染不受流程控制,如何在正确的时间发出断开连接回调?类似的问题也存在于异常处理、并发管理和安全性领域。
SWF 1.x 方法的另一个缺点是,在某些环境,特别是 JSF FacesServlet 中,“适配”Web Flow 需要重复劳动。在 JSF 的情况下,Web Flow 和 JSF 实现都在争夺 URL 的控制权以及如何管理服务器端状态。
欢迎 Spring Web Flow 2.0
从 Web Flow 2.0 M2 开始,整个 Web 请求生命周期,包括视图渲染阶段,现在都在 Spring Web Flow 的控制下。此外,Spring Web Flow 现在可以使用任何视图技术渲染响应,并对 Java Server Faces 和基于 Spring MVC 的视图提供一流支持。实际上,这意味着 SWF 2.0 是同类中少数几个提供统一控制器模型来处理所有类型的用户交互(无论是无状态还是有状态)并支持多种视图技术的框架之一。这也意味着现在可以使用原生 Web Flow 执行钩子来观察整个 Web 请求生命周期,从而可以在请求生命周期的适当点集中应用安全性、异常处理、性能管理、并发管理和持久化上下文管理策略。新的 SWF 2 架构,在 Spring MVC DispatcherServlet 内部运行,如下图所示。

微妙但重要的区别。
截至 Spring Web Flow 2.0 M2,已经验证了四种具体的 Web Flow 视图处理策略,任何 Web 应用程序都可以使用其中的一种或多种策略。下面依次重点介绍这些策略。
Java Server Faces
支持的第一种视图处理策略是 Java Server Faces。通过 Spring Faces 项目,SWF 引擎现在可以充当 JSF 的容器,并完全驱动 JSF UI 组件生命周期,将 SWF 应用程序控制器模型的所有优势与 JSF UI 组件模型的所有优势结合起来。因此,我们为社区带来了以下好处:
- 一种以 Spring 为中心的方式来配置和部署使用 JSF 的 Spring Web 应用程序。要启动和运行,您需要部署一个 Spring Web Servlet 并将其指向您的 bean 定义文件,这与您今天配置 Spring MVC Web 应用程序的方式非常相似。不需要 faces-config.xml 或任何其他特殊的 JSF 文件。这使得 Spring 用户可以非常轻松地利用 JSF 而无需承担任何传统缺点。如果愿意,您甚至可以在 Spring MVC DispatcherServlet 内部使用 JSF,当在“嵌入式”模式下运行时。
- 自动支持 POST+REDIRECT+GET 模式,以防止在使用浏览器导航按钮时出现重复提交和浏览器警告。这出于同样的原因是可能的:Spring Web Flow 原生支持此模式,并且我们已将 JSF 集成到我们的模型中。
- 流程管理的 UI 组件状态。这特别有趣,因为传统上使用 JSF 意味着需要大量的 HTTP Session 状态来存储组件树。JSF 组件状态现在完全作为 SWF FlowExecution 实例状态进行管理,这意味着该状态如何存储取决于使用的流程执行仓库。这意味着可以实现一个完全没有会话存储的 JSF 应用程序。这也意味着对于无状态或“REST-ful”交互,从不分配会话存储。这也意味着当为有状态流程执行分配会话存储时,分配的存储量更少,并且该状态的范围是明确的(并且在实践中通常比传统的 JSF Web 应用程序更短)。
外部系统
我们验证的第二种视图处理策略是 SWF 引擎通过 HTTP 与外部系统和会话上下文通信的能力(尽管 API 是协议无关的)。一个很好的例子是电子购物网站可能会使用像 paypal 这样的第三方服务。假设您正在引导用户进行电子购物体验,并且作为该体验的一部分,您需要暂停并将用户重定向到 paypal 完成支付授权过程。Paypal 在接管支付授权控制权后,会回调您,以便您可以从暂停的地方恢复用户的电子购物体验。通常通过向外部服务传递一个回调 URL 来支持此功能,外部服务完成操作后将重定向到该 URL。
这种模式现在已由 SWF 引擎原生支持。要执行类似操作,您只需向外部系统发出“外部重定向”。Spring Web Flow 现在负责在发送到外部系统的重定向中嵌入适当的流程执行回调 URL。
资源
我们验证的第三种视图处理策略是能够从资源包(如 .jar 文件)提供资源内容(图像、javascript 文件、css 文件等)。当 Ext 和 Dojo JavaScript 小部件由 Spring Faces JSF 组件渲染时,Spring Faces 安装了一个预定义的“REST-ful”流程,用于提供 Ext 和 Dojo 库所需的 Javascript 和 CSS 资源。
Spring MVC 视图
最后,我们验证的第四种视图处理策略是能够提供基于 Spring MVC 的视图。这使得现有的 Spring MVC 视图模板能够像以往一样与 Web Flow 2.0 协同工作,这对于我们现有的 Spring MVC 和 Web Flow 用户来说非常重要。
结论
本文对 Spring Web Flow 2.0 版本的目标以及最近发布的
Spring Web Flow 2.0 M2 版本中奠定的架构基础进行了高级概览。敬请关注后续文章,这些文章将重点介绍 M2 中的主要新功能以及我们目前正在为 M3 忙于实现的新功能。Spring Faces 项目负责人 Jeremy Grelle 特别有很多关于新的 JSF 和 Ajax 支持的激动人心的内容要分享!