流程实例,任务,执行对象控制流程的执行

点击下载Demo,对应的类是test.3

1.第一步首先是部署流程定义

我们将之前画的test.1bpmn图再部署一次(这里我重新创建了Activiti的23张表)

流程监控java代码设计_数据

运行单元测试,结果如下:

流程监控java代码设计_Test_02

现在流程已经部署好了,接下来启动该流程,开始走业务流程,我们使用流程定义的key启动流程,代码如下:

/**
     * 启动流程实例(范冰冰点击了请假申请)
     */
    @Test
    public void startProcessInstance(){
        String key = "myProcess_1";
        ProcessInstance pi = processEngine.getRuntimeService()   // 与正在执行的流程实例和执行对象的相关Service
                        .startProcessInstanceByKey(key); // 使用流程实例的key启动流程实例(使用id也可以),key对应test1.bpmn文件的id属性,使用key启动的好处是,能够默认使用流程定义的最新版本启动

        System.out.println("流程实例Id:"+pi.getId());
        System.out.println("流程定义Id:"+pi.getProcessDefinitionId());
    }

运行结果如下:

流程监控java代码设计_数据_03

这一步我们操作的表有:

act_ru_execution (运行时流程实例表) 如果是用户任务节点,同时也会在act_ru_task添加一条记录

act_ru_task (运行时任务节点表) 只有节点是UserTask的时候,在表中才会存在数据

act_ru_identitylink (任务办理人表) 主要存储任务节点与参与者的相关信息

其他的还有: act_hi_actinst 历史节点表 (完成的,没完成的任务都会记录在这里) act_hi_identitylink 历史流程人员表 act_hi_procinst 历史流程实例表 act_hi_taskinst 历史任务实例表

这个时候我们可以在act_ru_execution表里面看到,ID和PROC_INST_ID是一样的,因为,如果是单例流程,执行对象ID就是流程实例ID,如果一个流程有分支和聚合,那么执行对象ID和流程实例ID就不相同,一个流程中,流程实例只有1个,执行对象可以存在多个 。

我们现在来看看act_ru_execution (运行时流程实例表)

流程监控java代码设计_流程监控java代码设计_04

act_ru_task (运行时任务节点表)

流程监控java代码设计_流程监控java代码设计_05

act_ru_identitylink (任务办理人表)

流程监控java代码设计_Test_06

正在办理的任务表有了数据,那么对应的历史表也有了数据,在Activiti里面,将正在执行的任务的数据和历史数据分开,因为在真是的业务中,对历史任务的查看远远低于对正在办理的任务的查看,所以这是Activiti为了提高速度而做的设计。

2.查看我的任务

当流程启动之后(范冰冰提交申请之后),任务就进行到了下一个环节(审批环节task1),当前环节的办理人可以查看自己的任务了。

/**
     * 查看我的个人任务(李晨)
     * 查询相关的表:act_ru_task
     */
    @Test
    public void findMyPersonalTask(){
    	String assignee = "李晨";	// 范冰冰提交申请之后,当前审批人是李晨(对应节点是“提交申请(李晨)”)
    	List<Task> list = processEngine.getTaskService()	// 与正在执行的任务管理相关的Service
    			.createTaskQuery()		// 创建任务查询对象
    			.taskAssignee(assignee)	// 指定个人任务查询,指定办理人
    			.list();
    	
    	if(list != null && list.size() > 0){
    		for(Task task:list){
    			System.out.println("===================== 查看个人任务 begin ==========================");
    			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("===================== 查看个人任务 end ============================");
    		}
    	}
    }

运行后输出结果如图:

流程监控java代码设计_流程监控java代码设计_07

当任务到达我这里的时候,需要办理任务,使任务进行到下一个环节:

/**
     * 完成我的任务
     */
    @Test
    public void completeMyPersonalTask(){
    	String taskId = "2504"; // 李晨的任务Id,任务id(act_ru_task表)
    	processEngine.getTaskService()
    		.complete(taskId);
    	
    	System.out.println("完成任务,任务ID:"+taskId);
    }

运行单元测试输出结果如下:

流程监控java代码设计_数据_08

当我们完成任务之后,我们去act_ru_execution( 运行时流程执行实例表)去看看

流程监控java代码设计_数据_09

我们会发现,还是只有一条数据除了ACT_ID改变了之外其他的都没有改变,这是因为,一个流程实例在act_ru_execution只会有一条记录,每一个节点完成任务之后都会去修改ACT_ID,改为下一个节点的id。这个时候如果流程还没有完成,act_hi_procinst 历史流程实例表 不会有任何改变

我们再到act_ru_task (运行时任务节点表)看看

流程监控java代码设计_流程监控java代码设计_10

我们发现,act_ru_task 运行时任务节点表 的的 ASSIGNEE(办理人) 、 NAME、 TASK_DEF_KEY 改变为下一个节点的数据,这个时候我们可以看到 ASSIGNEE变成了“冯小刚”,那么这个时候,李晨就不能查看这条记录了,我们查看李晨的个人任务,会发现结果为空

这个时候我们去act_hi_taskinst (历史节点表) 去查看

流程监控java代码设计_Test_11

我们会发现该流程有了3条记录,第二条是第一个UserTask节点的数据,它的ASSIGNEE(办理者)为“李晨”,我们可以看到它的END_TIME已经有了值,说名“李晨”, 的任务任务已经完成了,我们看第三条记录,它的ASSIGNEE是“冯小刚”,它的END_TIME还是空的,说明“冯小刚”的任务还没有完成

这个时候我们可以查看冯小刚的个人任务了,代码如下:

/**
     * 查看我的个人任务(冯小刚)
     * 查询相关的表:act_ru_task
     */
    @Test
    public void findMyPersonalTask2(){
    	String assignee = "冯小刚";	// 李晨完成办理之后,当前审批人是冯小刚,这个时候李晨已经无法查看到任务了,不信你去上面试试
    	List<Task> list = processEngine.getTaskService()	// 与正在执行的任务管理相关的Service
    			.createTaskQuery()		// 创建任务查询对象
    			.taskAssignee(assignee)	// 指定个人任务查询,指定办理人
    			.list();
    	
    	if(list != null && list.size() > 0){
    		for(Task task:list){
    			System.out.println("===================== 查看个人任务 begin ==========================");
    			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("===================== 查看个人任务 end ============================");
    		}
    	}
    }

运行单元测试后结果如下:

流程监控java代码设计_Test_12

我们再来完成冯小刚的任务,我们再到数据库看看有什么变化

act_ru_execution( 运行时流程执行实例表),发现还是一条数据

流程监控java代码设计_数据_13

act_ru_task (运行时任务节点表),正在执行的任务还是只有一个,但是ASSIGNEE变成了“周星驰”,任务到达了第三个节点

流程监控java代码设计_Test_14

现在周星驰可以查看自己的任务了

/**
     * 查看我的个人任务(周星驰)
     * 查询相关的表:act_ru_task
     */
    @Test
    public void findMyPersonalTask3(){
    	String assignee = "周星驰";	// 冯小刚完成办理之后,当前审批人是周星驰,这个时候冯小刚已经无法查看到任务了,不信你去上面试试
    	List<Task> list = processEngine.getTaskService()	// 与正在执行的任务管理相关的Service
    			.createTaskQuery()		// 创建任务查询对象
    			.taskAssignee(assignee)	// 指定个人任务查询,指定办理人
    			.list();
    	
    	if(list != null && list.size() > 0){
    		for(Task task:list){
    			System.out.println("===================== 查看个人任务 begin ==========================");
    			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("===================== 查看个人任务 end ============================");
    		}
    	}		
    }

运行单元测试输出结果如下:

流程监控java代码设计_数据_15

OK,现在任务已经到达了最后一个节点,我们来完成最后一个任务

/**
     * 完成我的任务(周星驰)
     */
    @Test
    public void completeMyPersonalTask3(){
    	String taskId = "7502"; // 周星驰的任务Id
    	processEngine.getTaskService()
    		.complete(taskId);
    	
    	System.out.println("完成任务,任务ID:"+taskId);
    }

运行输出结果如下:

流程监控java代码设计_流程监控java代码设计_16

现在整个流程已经结束了,看看数据库会有什么变化

act_ru_execution (运行时流程实例表),空空如也

流程监控java代码设计_Test_17

act_ru_task (运行时任务节点表),也是空空如也

流程监控java代码设计_数据_18

act_ru_identitylink (当前任务办理人表),也是没有了数据

流程监控java代码设计_流程监控java代码设计_19

act_hi_procinst(历史流程实例表)还是只有一条数据(流程实例只有一个),但是END_TIME和其他等等的属性有了值,说明流程已经结束了

流程监控java代码设计_数据_20

act_hi_taskinst(历史任务实例表),从这个流程实例的开始节点到结束节点的数据都有了,ASSIGNEE 为“周星驰”的那条记录的END_TIME有了值,说明“周星驰”的任务结束了

流程监控java代码设计_流程监控java代码设计_21

act_hi_identitylink (历史任务办理人表)有了李晨、冯小刚、周星驰三条记录

流程监控java代码设计_数据_22

当流程结束之后,所以的数据会保存的相关的历史表里面,运行时流程相关的数据会被删除,工作流划分的比较细,正在运行的和历史的分开,这样就能提高查询效率。

OK,到这里,整个流程实例的讲解也就结束了!!!