本博文主要讲如何Spring WeB Flow的原理以及如何使用
可以参考 Spring Web Flow 2.0 入门详解,这篇博文讲的太好了.
1背景介绍
1.1背景
平时中我们尝具有一些流程化的操作,如上网购物时,一般时选中物品–>加入购物车–>提交订单–>付款.在spring里就专门为这种流程化操作提供一个Web框架,Spring Web Flow,它时Spring的一个子项目,并不属于Spring的一部分. Spring Web Flow能够很好的将流程的定义,实现流程的行为及视图分开,进行解耦.而strust2的流程定义很难做到流程定义和实现行为分开,而且其流程定义的比较散散乱,一般时将流程定义在实现中,即在action内部通过判断条件进行流程跳转.strust2的流程流程可读性差.
1.2原理介绍
需要声明的是Spring Web Flow 的构建时基于SpringMVC之上的,所以所有的流程都是由SpringMVC的DispatcherServlet负责管理和转发.但DispatcherServlet并不能直接知道流程请求和流程行为的对应关系,和bean使用一样,流程需要定义,加载,注册和执行.Spring Web Flow的工作是通过配置流程注册表将应用中定义的流程进行加载并注册,当用户进入一个流程时,通过装配了流程注册表引用的FlowHanderMapping查找用户请求URL的对应流程,再通过FlowHandlerAdapter相应该流程请求.FlowHandlerAdapter配置了一个流程执行器,可以执行流程请求.
上面说的流程是处理一个事情的步骤,流程由三个主要元定义的:状态,转移和流程数据.
状态:流程中事件发生的地点.
转移:连接状态的线,从一个状态转到另一个状态.
数据:流程在执行和转移时携带的数据.
2.相关概念及配置
接下来我们进行一些配置,包括jar,注册表配置,执行器配置,处理请求配置等.
2.1.Spring Web Flow的相关包
- org.springframe.binding-x.x.x.RELEASE.jar
- org.springframe.faces-x.x.x.RELEASE.jar
- org.springframe.js-x.x.x.RELEASE.jar
- org.springframe.js.resources-x.x.x.RELEASE.jar
- org.springframe.webflow-x.x.x.RELEASE.jar
2.2配置流程注册表
注册表的主要工作时负责流程的定义查找,加载和注册,不负责创建和执行.注册好的流程提供给执行器,是执行器能够查找并使用这些流程.
1 | <flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows"> |
这里定义了流程注册表flowRegistry,指定了流程定义的文件位置在/WEB-INF/flows下,并且文件名字以-flow.xml.注册表将匹配的所有文件加载,并注册这些流程.
当然也可以通过flow-location-pattern指定文件名字来加载,还可以为该流程设置具体的ID.
2.3织入流程执行器
主要负责驱动流程的执行.当用户进入一个流程时,流程执行器就会为用户创建并启动一个流程.
1 | <flow:flow executor id="flowExecutor" flow-refistry="flowRegistry"/> |
2.4 处理流程请求
配置FlowHandlerMapping
1 | <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping"> |
配置FlowHandlerAdapter
1 | <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"> |
2.5 流程组件
2.5.1 状态
状态包括是行为(action),决策(decision),结束(end),子流程(subflow)或视图(view)类型.
1)视图(view):为用户展现信息,支持任意视图类型.
有3种写法
1 | 1. < view-state id="welcome"/> id对应流程内标状态和试图名称 |
2)行为状态
行为状态是应用程序自身执行的任务,可以理解为方法调用,根据调用结果转移状态.
1 | <action-state id="saveOrder" |
pizzaFlowActions是指某个bean ID
3)决策状态
通过条件判断决定转移.
1 | <decision-state id="checkDeliverArea" > |
4)子流程状态
运行一个正在执行的流程调用另一个流程.类似于一个方法调用另一个方法
1 | <subflow-state id="order" subflow="pizaa/order" |
"< input >" 是作为子流程的输入.
5)结束状态
1 | <end-state id="customerReady"> |
2.5.2转移
局部转移,在某个状态下适用
1 | < transition to="">:从当前状态转移到to对应的状态 |
全局转移,所有状态都可以
1 | < global-transitions> |
2.5.3数据
1.声明变量包含3种
1 | < var name="" class=""> |
2.6定义切入点
切入点有5个
flow start on-start flow 执行之前
state entry on-entry 进入某个 state 之后,做其他事情之前
view render on-render 在进入 view 的 render 流程之后,在 view 真正 render出来之前
state exit on-exit 在退出 state 之前
flow end on-end flow 执行结束之后
如在进入试图render时切入,一般是声明变量何时定义和初始化:
1 | <view-state id="viewCart" view="viewCart" > |
2.作用域
- Conversation:最高层级的流程开始创建时创建,在最高层级的流程结束时销毁.最高层级流程与其子进程共享.此范围内的对象与 flow 范围对象基本相似,唯一不同在于 conversation 范围内的对象所在的 flow 如果调用了其他 subflow,那么在 subflow 中也可访问该对象。(也就是说:subflow中能够访问conversation中的对象)
- Flow: 流程开始创建时创建,在流程销毁时销毁.
- Request:当请求进入流程时创建,在流程返回时销毁
- Flash:当流程开始创建时创建,在流程销毁时销毁.在视图状态渲染后它也会销毁.
- View:进入视图状态时创建,退出这个状态时销毁.
flow 范围和 conversation 范围的使用也就突破了 Java Servlet 规范中 session 范围和 request 范围的局限,真正做到了自由定制。
var 始终时流程作用域
set 和 evaluate通过name 和result属性前缀指定作用域
小结
- Spring Web Flow主要用于流程编程,实现了流程定义,流程行为和视图解耦.
- Spring Web Flow在springMVC基础上创立. 需要DisptacherFilter分配
- 整个流程是流程注册表查找,加载和注册流程定义.FlowHandlerMapping根据用户请求查找URL对应流程,并使用FlowHandlerAdapter执行.
- 流程由三个主要元定义的:状态,转移和流程数据.
- 状态包括是行为(action),决策(decision),结束(end),子流程(subflow)或视图(view)类型
- 转移分为局部和全局,共三种配置方法
- 数据作用域有5种:Flow,Conversation,Request,Flash,View