Activiti工作流10.排他网关

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activiti工作流10.排他网关相关的知识,希望对你有一定的参考价值。


很久没有更新Activiti的文章,有朋友想看之后的技术总结,我这里就顺着上一次的记忆继续写,把这个系列完结了。



上一次介绍了Activiti中的其中一种模式“连线”,该模式即是一件任务可能要分多种情况,有些情况需要走一个复杂流程,有些情况需要走简单流程,就如同一条河的分支一样。



而本次介绍的是Activiti的另一种模式“排他网关(ExclusiveGateWay)”。


我们打开Eclipse中的某个bpmn的流程图视图,在左侧的编辑框中就可以看到有一个“GateWay”的选项,其中有“ExclusiveGateWay”和“ParallelGateWay”两个选项,其中“ExclusiveGateWay”就是我们要讲的排他网关:


【Activiti工作流】10.排他网关_bpmn


什么是网关(GateWay)?其实网关说白了就是事件流到某一个核心节点,该节点需要做一个判断,如果判断符合某一个逻辑,那么事件就流到合适的路径上去,进行了分支。而做判断的节点就是所谓的网关。



为了让大家更加清晰的理解排他网关,我们利用之前的工程做一个排他网关的样例。


我们要做一个类似“费用报销申请”的流程图,申请人进行费用报销申请,然后利用网关来区分费用的大小。要求有达成如下条件进行不同的分支操作:


(1)如果报销金额大于500,小于等于1000,则任务流转至部门经理审批;


(2)如果报销金额小于等于500,默认流转至财务处审批;


(3)如果报销金额大于1000,则任务流转至总经理审批;



下面我们来利用排他网关来实现这个实例。


首先在测试工程“”中创建一个新的包“”来放置本次测试样例的代码:


【Activiti工作流】10.排他网关_Activiti_02


然后在该包下新建一个bpmn的流程图:


【Activiti工作流】10.排他网关_conditionExpression_03


进入编辑界面后,先创建一个StartEvent节点和一个连线以及一个UserTask:


【Activiti工作流】10.排他网关_conditionExpression_04


其这里的UserTask是报销人的申请任务。该UserTask的Properties参数如下:


【Activiti工作流】10.排他网关_Activiti_05


【Activiti工作流】10.排他网关_Activiti_06


然后在下面创建3个任务,分别是排他网关根据情况进行分支后的任务:


【Activiti工作流】10.排他网关_排他网关_07


三个任务的Properties参数如下:

【Activiti工作流】10.排他网关_bpmn_08

【Activiti工作流】10.排他网关_ExclusiveGateWay_09

【Activiti工作流】10.排他网关_Activiti_10

【Activiti工作流】10.排他网关_排他网关_11

【Activiti工作流】10.排他网关_Activiti_12

【Activiti工作流】10.排他网关_排他网关_13


然后我们在申请任务和下面三个任务之间添加一个排他网关:


【Activiti工作流】10.排他网关_conditionExpression_14


然后三个任务最终流向结束节点:


【Activiti工作流】10.排他网关_ExclusiveGateWay_15



然后最重要的几步来了,首先定义排他网关下面的三条线的Name和相关message判断信息:


总经理审批的流线:


【Activiti工作流】10.排他网关_Activiti_16

【Activiti工作流】10.排他网关_bpmn_17

【Activiti工作流】10.排他网关_排他网关_18

部门经理审批的流线:


【Activiti工作流】10.排他网关_ExclusiveGateWay_19

【Activiti工作流】10.排他网关_Activiti_20

【Activiti工作流】10.排他网关_ExclusiveGateWay_21


对于财务的线,我们没有必要为其设备“$message<=500”的条件,直接将其设置为排他网关的默认Task(将指向该Task的线的id给排他网关的Defalut flow属性),即是不满足其它两个条件时,默认走该Task:


【Activiti工作流】10.排他网关_conditionExpression_22

【Activiti工作流】10.排他网关_bpmn_23


到此我们的排他网关的流程图就画好了,Ctrl+S保存流程图,可以看到在相应的包下生成了一个png的流程图片:


【Activiti工作流】10.排他网关_conditionExpression_24



然后我们创建名为“ExclusiveGateWayTest”的测试类进行测试,先编写一个部署流程的部署方法:


package cn.com.eclusiveGateWay;
import java.io.InputStream;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.junit.Test;

public class ExclusiveGateWayTest //获取流程引擎对象
//getDefaultProcessEngine方法内部会自动读取名为activiti.cfg.xml文件的配置信息
ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();

/**部署流程定义*/
@Test
public void deploymentProcessDefinition_inputStream()
//获得上传文件的输入流
InputStream inputStreamBpmn=this.getClass().getResourceAsStream("exclusiveGateWayFlow.bpmn");
InputStream inputStreamPng=this.getClass().getResourceAsStream("exclusiveGateWayFlow.png");
//获取仓库服务,从类路径下完成部署
RepositoryService repositoryService=processEngine.getRepositoryService();
DeploymentBuilder deploymentBuilder=repositoryService.createDeployment();//创建一个部署对象
deploymentBuilder.name("排他网关");//添加部署的名称
deploymentBuilder.addInputStream("exclusiveGateWayFlow.bpmn", inputStreamBpmn);
deploymentBuilder.addInputStream("exclusiveGateWayFlow.png", inputStreamPng);
Deployment deployment=deploymentBuilder.deploy();//完成部署

//打印我们的流程信息
System.out.println("部署Id:"+deployment.getId());
System.out.println("部署名称Name:"+deployment.getName());

执行该部署方法,可以看到控制台输出了部署信息:


【Activiti工作流】10.排他网关_排他网关_25



然后在数据库中,可以看到act_re_deployment部署对象表、act_re_procdef流程定义表以及act_ge_bytearray资源文件表中都生成了该次部署的流程定义信息:


【Activiti工作流】10.排他网关_conditionExpression_26

【Activiti工作流】10.排他网关_ExclusiveGateWay_27

【Activiti工作流】10.排他网关_conditionExpression_28


然后在ExclusiveGateWayTest中编写启动实例方法:


/**启动流程引擎*/
@Test
public void startProcessInstance()
//获取流程启动Service
RuntimeService runtimeService=processEngine.getRuntimeService();
//使用流程定义的key,key对应bpmn文件对应的id,
//(也是act_re_procdef表中对应的KEY_字段),默认是按照最新版本启动
String processDefinitionkey="myProcess";//流程定义的key就是myProcess
//获取流程实例对象
ProcessInstance processInstance=runtimeService.startProcessInstanceByKey(processDefinitionkey);
System.out.println("流程实例ID:"+processInstance.getId());//流程实例ID
System.out.println("流程定义ID:"+processInstance.getProcessDefinitionId());//流程定义ID


运行测试方法,启动该流程:


【Activiti工作流】10.排他网关_ExclusiveGateWay_29


在数据库中的act_run_task表中有一个正在执行的任务:


【Activiti工作流】10.排他网关_排他网关_30



那么我们编写查询“姜晓宏”流程任务的方法,查看姜晓宏当前的待办任务:


/**查询当前的个人任务(实际就是查询act_ru_task表)*/
@Test
public void findMyPersonalTask()
String assignee="姜晓宏";
//获取事务Service
TaskService taskService=processEngine.getTaskService();
List<Task> taskList=taskService.createTaskQuery()//创建任务查询对象
.taskAssignee(assignee)//指定个人任务查询,指定办理人
.list();//获取该办理人下的事务列表

if(taskList!=null&&taskList.size()>0)
for(Task task:taskList)
System.out.println("任务ID:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务的创建时间:"+task.getCreateTime());
System.out.println("任务办理人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
System.out.println("执行对象ID:"+task.getExecutionId());
System.out.println("流程定义ID:"+task.getProcessDefinitionId());
System.out.println("#############################################");


查询结果:


【Activiti工作流】10.排他网关_ExclusiveGateWay_31



可以看到他的任务ID为2304,下面编写完成任务的测试方法,定义流程变量的名称为message,值为450:


/**完成我的任务*/
@Test
public void completeMyPersonalTask()
String taskId="2304";//上一次我们查询的任务ID
//完成任务的同时,设置流程变量,使用流程变量用来制定完成任务后,下一个连线,
//对应exclusiveGateWayFlow.bpmn文件中$message==450
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("message", 450);
TaskService taskService=processEngine.getTaskService();
taskService.complete(taskId,variables);//完成taskId对应的任务,并附带流程变量
System.out.println("完成ID为"+taskId+"的任务");

完成结果:


【Activiti工作流】10.排他网关_ExclusiveGateWay_32



按照流程图来说,节点应该流向默认的“财务”处,即是“张丽”来办理该任务,所以我们查询张丽的代办任务:


【Activiti工作流】10.排他网关_conditionExpression_33



然后执行张丽的任务:


【Activiti工作流】10.排他网关_排他网关_34


最后任务完成:


【Activiti工作流】10.排他网关_ExclusiveGateWay_35


历史的任务节点:


【Activiti工作流】10.排他网关_bpmn_36


流程中出现的流程变量:


【Activiti工作流】10.排他网关_bpmn_37



然后重新启动一个流程,将message设置为700:


【Activiti工作流】10.排他网关_conditionExpression_38

【Activiti工作流】10.排他网关_Activiti_39

【Activiti工作流】10.排他网关_bpmn_40

此时流程流向了部门经理:


【Activiti工作流】10.排他网关_ExclusiveGateWay_41


执行2704任务后流程结束:


【Activiti工作流】10.排他网关_conditionExpression_42



最后再重启一个流程,将message设置为1300:


【Activiti工作流】10.排他网关_排他网关_43

【Activiti工作流】10.排他网关_conditionExpression_44

【Activiti工作流】10.排他网关_排他网关_45

此时流程流向了总经理:


【Activiti工作流】10.排他网关_bpmn_46


执行3004任务后流程结束:


【Activiti工作流】10.排他网关_conditionExpression_47


总结:


1)一个排他网关对应一个以上的顺序流。



2)由排他网关流出的顺序流都有一个conditionExpression元素,在内部维护返回boolean类型的决策结果。



3)决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索,如果发现第一条决策结果为true或者没有设置条件的(默认成立),则流出。



4)如果没有任何一个出口符合条件,则抛出异常。



5)使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有符合的条件,则执行默认的连线。


BOS项目 第10天(activiti工作流第二天,流程变量组任务排他网关spring整合activiti项目中实现流程定义管理)

BOS项目笔记 第10

 

今天内容安排:

1、流程变量(设置、获取)

2、组任务(候选人、候选组)

3、排他网关使用

4spring整合activiti

5、将activiti应用到bos项目中

6、在bos项目中实现流程定义管理(部署、查询、查看png、删除)

 

1. 流程变量

 

1.1 设置流程变量的方式

方式一:启动流程实例时设置

 

方式二:办理任务时设置

 

方式三:使用RuntimeServiceset方法设置

 

方式四:使用TaskServiceset方法设置

 

注意:如果设置的是自定义的类型,需要实现序列号接口

1.2 获取流程变量的方式

方式一:使用RuntimeServiceget方法获取

 

方式二:使用TaskServiceget方法获取

 

方式三:使用框架提供的表单式获取

 

 

2. 组任务操作

2.1 候选人组任务(了解)

2.2 候选组组任务(重点)

 

创建组:

 

创建用户:

 

建立用户和组的关系:

 

查询组任务:

 

拾取组任务:

 

 

3. 排他网关使用

 

 

 

 

4. spring整合activiti框架

修改spring配置文件,使用spring提供的流程引擎配置对象:

 

提供数据源和事务管理器

 

使用spring提供的流程引擎工厂bean创建流程引擎对象

 

读取spring配置文件,创建spring工厂,从工厂中获取对象

 

 

5. bos中实现流程定义管理

修改admin.json,加入工作流相关的菜单

5.1 查询流程定义

 

 

第一步spring配置文件中配置activiti框架使用的Service

 

第二步提供ProcessDefinitionAction,使用注解注入RepositoryService提供list方法

 

第三步:配置struts.xml

 

第四步:提供processdefinition_list.jsp页面,展示流程定义列表数据

 

 

5.2 部署流程定义

第一步:提供流程定义部署页面

 

第二步:在Action中提供deploy方法,提供zipFile的属性和相应的set方法接收上传的文件

 

第三步:配置struts.xml

5.3 查看png图片

第一步:修改jsp页面中弹出窗口的效果

 

第二步:在Action中提供png方法,提供id属性和set方法

 

第三步:配置struts.xml

 

 

5.4 删除流程定义

第一步:在jsp页面中提供删除按钮,指定onclick事件

 

 

第二步:在Action中提供delete方法

 

第三步:在jsp页面中根据deltag标志位判断删除是否成功

 

以上是关于Activiti工作流10.排他网关的主要内容,如果未能解决你的问题,请参考以下文章

BOS项目 第10天(activiti工作流第二天,流程变量组任务排他网关spring整合activiti项目中实现流程定义管理)

Activity并行网关和排他网关

Activiti网关-排他网关

activiti-排他网关

排他网关(ExclusiveGateWay)

activiti排他网关