fire workflow开发手册10.docx
《fire workflow开发手册10.docx》由会员分享,可在线阅读,更多相关《fire workflow开发手册10.docx(18页珍藏版)》请在冰点文库上搜索。
fireworkflow开发手册10
FireWorkflow开发手册1.0
框架说明
基础说明
阅读本文档前请确认已经阅读过下面两篇文档,并对该两篇文档有了较深刻的认识。
●WSI开发手册1.0.doc
●99_FireWorkflow工作流原理、设计与应用.pdf
FireWorkflow是由国人开发的一个开源工作流引擎,可以解决常见的带有工作流需求的案例。
本文的编写目的是让读者能快速的基于FireWorkflow进行工作流相关开发。
基础设施
本系统的主体开发框架是WebWork+Spring+iBatis,在这之上引入FireWorkFlow引擎。
框架结构
由于框架是基于WSI框架的,因此这里的编码结构和原来的WSI的编码风格完全一致。
工作步骤
工作步骤总体介绍
要做FireWorkflow相关的开发,大约需要做以下的工作。
1.配置FireWorkflow环境
2.业务流程数据库设计
3.画流程图
4.编写流程执行者Handler
5.在业务代码中加入流程代码
配置FireWorkflow环境
FireWorkflow所需要用到的东西可以在公司的KM下找到。
Jar包和脚本等在fireflow例子.zip里都能找到。
导入FireWorkflow的jar包
将FireWorkflow及其需要使用的第三方jar包导入到业务系统工程里,注意不要和工程里已有的jar冲突:
拷贝以上jar包至项目的Web-INF/lib目录下,并配置好buildpath。
在数据库中执行FireWorkflow流程库脚本
由于FireWorkflow采取了业务和流程完全分离的模式,因此程序编写人员并不需要关注流程引擎的工作细节,但是流程引擎需要使用自己的流程表,因此流程库的脚本还是需要执行的。
这些脚本创建的7张流程表为:
●t_ff_rt_workitem;
●t_ff_rt_token;
●t_ff_rt_taskinstance;
●t_ff_rt_procinst_var;
●t_ff_rt_processinstance;
●t_ff_hist_trace;
●t_ff_df_workflowdef;
这7张表的关系,详见99_FireWorkflow工作流原理、设计与应用.pdf,这里就不赘述了。
配置文件
我们需要拷贝spring配置文件到系统目录下:
还有个properties也需要拷贝到系统目录下,将里面的内容置空(KM里的例子里是有配置的,这个是对流程库的task做扩展,以前用Hibernate这么做是有意义的,我们持久层使用的是IBatis,做这样的继承意义不大)。
将内容置空或注释掉。
接下来,我们配置Ibatis的sqlmapconfig,设置流程库的7张表。
这些sql的xml文件已经包含在了FireWorkflow的jar里了。
配置流程设计器eclipse插件
在KM里导出FireflowDesigner4Eclipse_1.0.0_beta_build090723.jar,然后将这个jar放在eclipse的plugins目录下,重启eclipses。
业务流程数据库设计
由于FireWorkflow采取了业务和流程完全分离的模式,因此流程库和业务库的关联关系通常有两种方式。
一是在业务库里添加流程库的关联字段,二是在流程库里添加业务库的字段。
由于FireWorkflow自己对流程库进行管理操作,我们应当避免直接修改流程库。
因此我们选择第一种方式,在业务库添加流程库的关联字段。
由于流程实例信息基本可以拿到一个流程的所有的信息,因此我们在设计的时候,可以在相关的业务表里关联流程实例表的主键,如下图的例子。
画流程图
在画流程图之前,确保已经正确的安装了流程设计器。
主要步骤如下:
画流程图,请主要参考99_FireWorkflow工作流原理、设计与应用.pdf,这里就不赘述了。
一个画好的请假流程图如下。
设置流程执行Handler
需要注意的是,每个task里的workitem可以指定执行者,这个是通过handler来指定的,下一节我们将介绍Handler的代码的编写。
设置流程执行相关参数
在流程的流转里,我们通常可能会用到各种参数。
具体参数的设置方法比较简单。
然后我们可以在流程的流转连接线处,设置流转条件,表达式里可以直接使用上面设置的参数。
表达式是按照ExpressionLanguage表达式的规则来的。
提醒一点,流程库里参数value使用的字段是varchar2。
而我们使用的ibatis,在映射boolean型参数值到数据库的varchar2字段的时候,会自动转成1和0。
因此建议原本要使用boolean型参数的地方true和false,都用Integer的1和0代替。
绑定流程图到程序里
程序读取我们所设计的流程图有两种方式,一种是直接读xml,一种是从DB里读取T_FF_DF_WORKFLOWDEF这张表。
直接读xml的方式比较简单。
打开applicationContext-fireflow-engine.xml,设置definitionService为DefinitionService4FileSystem。
然后配置要读取的xml。
如果要读取数据库T_FF_DF_WORKFLOWDEF表的方式。
则配置definitionService为DefinitionService4DBMS。
数据库里的字段设置也比较简单。
几个比较关键的字段,其中PROCESS_CONTENT是放整个流程定义xml的全部内容。
VERSION字段提供了同一个流程定义的多个版本的实现。
而PROCESS_ID则是这个流程定义的标识。
编写流程执行者Handler
上一节提到流程的执行者是通过Handler来实现的。
那么我们如何编写Handler呢。
首先我们可以在代码目录下建一个编写handler的包,如下所示:
然后再在里面编写Handler。
实现IAssignmentHandler接口
所有的Handler必须实现IAssignmentHandler接口,这样,流程引擎才可以正常使用。
以下为一个例子。
assign方法有两个参数,一个是assignable,这个其实是taskinstance实例,可以直接转化成taskinstance。
然后继而可以那到流程实例的相关信息。
assignable有一个方法assignToActor(StringactorId)可以指定分配工作项给单个用户ID,还有一个方法assignToActors(Listactors)可以分配给多个用户。
而下图表示了如何设置一个人完成即可,还是需要全部用户都完成,才可完成该项任务。
另一个参数是performerName,这个是在画流程定义图的时候指定的。
在实际应用中,我们可以指定角色名为这个Name,然后在程序里可以拿到角色名,继而根据角色拿到多个用户,进而做进一步设置。
如果在Handler里要使用数据库操作,我们还可以使Handler继承我们的baseservice的实现类,或者fireflowService的实现类。
后面会提到fireflowService的实现类其实也是继承于Baseservice的实现类,其中多加了一个runtimeContext属性,这个runtimeContext是FireWorkflow引擎调用的一个接入口。
以下为继承FireflowServiceImpl的例子。
这样,在spring配置文件里设置注入dao,runtimeContext等bean后,handler里就可以使用ibatis接口或者工作流引擎接口做更多的事情。
在Spring配置文件里配置Handler
Handler必须在spring配置文件里配置后,才能被工作流引擎所使用。
首先我们新建一个spring配置文件。
然后在里面添加Handler的配置。
这些handler就是在画流程定义图的时候指定的。
如果handler继承了BaseServiceImpl或者FireflowServiceImpl了,那么在handler的配置里还需要加入dao,utilservice,runtimeContext等属性配置。
这个配置方法同业务系统service配置类似。
在业务代码中加入流程代码
业务代码里我们常用到的调用工作流接口的地方,主要是启动工作流,查询我要做的工作列表,查询我完成的工作列表,完成工作项,添加工作流程参数等等。
以下就主要介绍一下这几个方面。
其他更多的请查阅FireWorkflow的文档和API。
首先业务service如果要调用工作流引擎,请继承FireflowServiceImpl而不是BaseServiceImpl,这个和前面Handler那里的说明类似。
然后spring配置文件中多加一个runtimeContext的属性。
启动工作流
启动工作流,在这里主要就是创建一个新的流程实例。
创建流程的代码很简单,如下所示。
流程创建后,我们可以启动它,并返回该流程实例的唯一ID。
这样流程实例的唯一ID,就可以获得并保存在我们的业务库里了。
在流程被创建并且完成后,流程会自动进入第一个流程环节。
一般第一个流程环节的Hanlder里都是设置成了直接完成工作内容,例如下面的例子,我们可以根据流程实例的创建人的id来分配给第一个流程环节,并直接签收完成。
这样的好处是很明显的,由于我们业务系统通常都是在执行第一步的时候需要启动流程,也就是说,创建流程和执行第一步的通常都是同一个人。
因此这里流程启动后,直接就将第一个步骤同时也一并完成掉的。
查询我待办的工作列表
在流程的创建者创建完成后,流程会走入到后续的环节中。
后续的人如何去签收完成工作呢?
一般来说,在业务系统里会先提供一个查询Todo的工作列表的功能,然后在这个工作列表里挑选要完成的工作,再进行下一步操作。
查询Todo的工作列表,可能会涉及到几张表,其中流程库里的表主要提供查询条件检索,比如:
等待我完成的这个条件。
而真正在业务系统里要显示的表的内容,可能就是我们之前提到的关联了流程实例ID的表。
例如,审批假单,可能就需要把业务库里的请假表也查出来,这样就可以知道是谁请的假,请假类型,请假时间等等。
以下为一个例子。
翻页列表action和普通的翻页列表action类似,这里就不介绍了。
但是调用的service的得到Page的方法,可以由我们自己定义。
例如:
在ibatis的sql的xml文件里,我们用业务库的表联查流程库表。
例如:
这里我们联查了流程实例,任务和工作项三张流程库的表。
在下面的查询条件里,有workitemStatus和processInstanceStatus这两个属性。
通过设置这两个属性,可以得到不同的查询结果。
例如,workitemStatus设置为1,表示为running,即将需要做的。
关于workitem的status和processinstance的status值,参考如下:
IWorkitem里的定义:
publicstaticfinalintINITIALIZED=0;
publicstaticfinalintRUNNING=1;
publicstaticfinalintCOMPLETED=7;
publicstaticfinalintCANCELED=9;
IProcessInstance里的定义:
publicstaticfinalintINITIALIZED=0;
publicstaticfinalintRUNNING=1;
publicstaticfinalintCOMPLETED=7;
publicstaticfinalintCANCELED=9;
查询我完成的工作列表
查询完成的工作列表与上面查询将要做的工作类似,只是这里传入的workitemStatus应该是7,即completed。
完成工作项
完成工作项比较简单。
只是要注意的是,FireWorkflow里在完成工作项之前还有一个签收的动作。
如果不需要签收,则可以两个一起完成。
需要签收,就分步骤做。
为了完成工作项,我们需要有工作项的id,因此在上面查询待办或完成的工作列表的时候,请一并将workItemId也查出来,在完成单个工作的时候,再将workItemId传到后台。
完成工作项的示例代码如下:
添加工作流程参数
在业务代码里,当流程执行到某个环节的时候,我们可能需要给流程设定参数。
流程的参数是和整个流程实例相关的。
在整个流程实例的生命周期里,我们都可以创建或更新参数的值。
流程参数的设置也很简单,以下的参考代码就示例了如果是approver1就设置approver1的审批结果,否则设置approver2的审批结果:
注意事项
在我们持久层的serviceIbatis版本的实现中,有一些直接查询workitem的方法,存在一定的效率问题,不推荐使用。
实际过程中,查询Todo的或者Finished的工作项,应该按照上面介绍的方式,直接联查业务表和流程表。
而不是调用持久层service接口,仅仅查询流程库的内容。
下面的例子就是不推荐使用的效率较低的方法的核心实现。
我们可以看到,代码里循环的查询了数据库。
这种做法不太推荐,在以后的版本里,这些方法将会被标注成不推荐的方法。