Spring WeB Flow知识梳理

本博文主要讲如何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
2
3
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows">
    <flow:flow-location-pattern value="*-flow.xml" />
<flow:flow-registry>

这里定义了流程注册表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
2
3
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry" />
</bean>

配置FlowHandlerAdapter

1
2
3
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

2.5 流程组件

2.5.1 状态

状态包括是行为(action),决策(decision),结束(end),子流程(subflow)或视图(view)类型.
1)视图(view):为用户展现信息,支持任意视图类型.
有3种写法

1
2
3
1. < view-state id="welcome"/>  id对应流程内标状态和试图名称
2. < view-state id="welcome" view="greeting"/> 
3. < view-state id="takePlayment" model="flowScope.paymentDetails"> 绑定流程范围的paymentDetails对像

2)行为状态
行为状态是应用程序自身执行的任务,可以理解为方法调用,根据调用结果转移状态.

1
2
3
<action-state id="saveOrder" 
<evaluate expression="pizzaFlowActions.saveOrder(order)"/>
</action-state>

pizzaFlowActions是指某个bean ID
3)决策状态
通过条件判断决定转移.

1
2
3
4
5
<decision-state id="checkDeliverArea" >
<if test="pizzaFlowActions.checkDeliveryArea(customer.zipCode)"
then="addCustomer"
else="deliveryWarning" />
</decision-state>

4)子流程状态
运行一个正在执行的流程调用另一个流程.类似于一个方法调用另一个方法

1
2
3
4
<subflow-state id="order" subflow="pizaa/order"
<input name="order" value="order" />
<transition on="orderCreated" to="payment">
</subflow-state>
"< input >" 是作为子流程的输入.

5)结束状态

1
<end-state id="customerReady">

2.5.2转移

局部转移,在某个状态下适用

1
2
< transition to="">:从当前状态转移到to对应的状态
< transition on="" to=""> :如果触发了on对应的事件,则跳到to事件

全局转移,所有状态都可以

1
2
3
< global-transitions>
< transition on="" to="" />
< /global-transitions>

2.5.3数据

1.声明变量包含3种

1
2
3
< var name="" class="">
< evaluate result="" expression=""> expression中可以用SpEL.
<set name="" value=" " >value可以用SpEL.

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
2
3
4
5
6
<view-state id="viewCart" view="viewCart" >
<on-render>
<evaluate expression="productService.getProducts()"
result="viewScope.products"/>
</on-render>
</view-state>

2.作用域

  • Conversation:最高层级的流程开始创建时创建,在最高层级的流程结束时销毁.最高层级流程与其子进程共享.此范围内的对象与 flow 范围对象基本相似,唯一不同在于 conversation 范围内的对象所在的 flow 如果调用了其他 subflow,那么在 subflow 中也可访问该对象。(也就是说:subflow中能够访问conversation中的对象)
  • Flow: 流程开始创建时创建,在流程销毁时销毁.
  • Request:当请求进入流程时创建,在流程返回时销毁
  • Flash:当流程开始创建时创建,在流程销毁时销毁.在视图状态渲染后它也会销毁.
  • View:进入视图状态时创建,退出这个状态时销毁.
    flow 范围和 conversation 范围的使用也就突破了 Java Servlet 规范中 session 范围和 request 范围的局限,真正做到了自由定制。

var 始终时流程作用域
set 和 evaluate通过name 和result属性前缀指定作用域

小结

  1. Spring Web Flow主要用于流程编程,实现了流程定义,流程行为和视图解耦.
  2. Spring Web Flow在springMVC基础上创立. 需要DisptacherFilter分配
  3. 整个流程是流程注册表查找,加载和注册流程定义.FlowHandlerMapping根据用户请求查找URL对应流程,并使用FlowHandlerAdapter执行.
  4. 流程由三个主要元定义的:状态,转移和流程数据.
  5. 状态包括是行为(action),决策(decision),结束(end),子流程(subflow)或视图(view)类型
  6. 转移分为局部和全局,共三种配置方法
  7. 数据作用域有5种:Flow,Conversation,Request,Flash,View
0%