Activiti5入门--接收活动

学习完排他网关和并行网关后,本章我们来学习接收任务活动(receiveTask)。

接收任务是一个简单任务,它会等待对应消息的到达。 当前,官方只实现了这个任务的java语义。 当流程到达接收任务,流程状态会保存到数据库中,但是数据不会保存在任务相关的表中。

在任务创建后,意味着流程会进入等待状态, 直到引擎接收了一个特定的消息, 这会触发流程穿过接收任务继续执行。

从上面的定义可知,在任务创建后,流程会进入等待状态,直到引擎接收了一个特定的消息, 触发流程继续执行。

下面,我们还是先创建一个新包cn.demo.receivetask,并创建新类ReceiveTaskTest以及流程文件receiveTask.bpmn,然后,我们来定义一个新流程。

定义流程

接下来,我们来定义一个新流程。该流程每天汇总当日的销售额,并给老总发短信。

  1. 先创建一个开始节点
  2. 从Task工具箱中找到Receive Task,创建一个新的接收任务,设置其Name的值为汇总当日销售额
  3. 再次从Task工具箱中找到Receive Task,创建新的接收任务,设置其Name的值为给老总发短信
  4. 点击空白处,设置流程的Id值为receiveTask,设置流程的Name值为receiveTaskProcess
  5. 创建一个结束节点

在定义流程时,注意到,Receive Task没有办理人,即Assigee字段,我们不能调用taskService来完成任务,补习调用runTimeService的方法推动流程执行。

接收活动

部署启动运行流程

部署流程

和前面一样,我们先部署流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 部署流程定义
*/
@Test
public void deploymentProcessDefinition() {
InputStream inputStreamBpmn = this.getClass().getResourceAsStream("receiveTask.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("receiveTask.png");
Deployment deploy = processEngine.getRepositoryService() // 与流程定义和部署对象相关的Service
.createDeployment() // 创建一个部署对象
.name("开始活动") // 添加部署的名称
.addInputStream("receiveTask.bpmn", inputStreamBpmn)
.addInputStream("receiveTask.png",inputStreamPng)
.deploy(); // 完成部署
System.out.println("部署ID: " + deploy.getId());
System.out.println("部署名称: " + deploy.getName());
}

运行代码,输出结果

部署ID: 4901
部署名称: 开始活动

启动运行流程

部署流程成功之后,我们可以分三步走

  1. 启动流程实例
  2. 由于当流程执行到接收任务后,该流程会进入等待状态,所以,可以使用流程变量设置当日销售额,然后向后执行一步,使得流程继续执行
  3. 当流程执行完汇总当日销售额后,我们可以获取该值,再次向后执行一步,结束流程

现在,我们来看一下各步骤的代码

  1. 启动流程实例

    1
    2
    3
    4
    5
    6
    // 流程定义的key
    String processDefinitionKey = "receiveTask";
    ProcessInstance processInstance = processEngine.getRuntimeService()
    .startProcessInstanceByKey(processDefinitionKey);
    System.out.println("流程实例ID: " + processInstance.getId());
    System.out.println("流程定义ID: " + processInstance.getProcessDefinitionId());

    可以看到,该处代码和前面的代码基本是一样的

  2. 设置流程变量,向后执行流程

    由于接受活动不属于任务的一种,其数据不会出现在任务相关表中,因此,我们使用runTimeService执行相关数据的查询、流程变量设置以及向后执行流程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /*使用流程变量设置当日销售额,用来传递业务参数*/
    /*查询执行对象id*/
    Execution execution1 = processEngine.getRuntimeService()
    .createExecutionQuery() // 使用流程实例Id查询
    .processInstanceId(processInstance.getId())
    // 当前活动的Id,对应receiveTask.bpmn文件中的活动节点id的属性值
    .activityId("receivetask1")
    .singleResult();
    processEngine.getRuntimeService()
    .setVariable(execution1.getId(), "汇总当日销售额", 21000);
    /*向后执行一步,使得流程继续执行*/
    processEngine.getRuntimeService()
    .signal(execution1.getId());

    在该代码中,我们使用了runTimeService的signal方法来向后执行流程,在下一步中,也是如此。

  3. 获取流程变量,向后执行流程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /*从流程变量中获取汇总当日销售额的值*/
    /*查询执行对象id*/
    Execution execution2 = processEngine.getRuntimeService()
    .createExecutionQuery() // 使用流程实例Id查询
    .processInstanceId(processInstance.getId())
    // 当前活动的Id,对应receiveTask.bpmn文件中的活动节点id的属性值
    .activityId("receivetask2")
    .singleResult();
    Integer value = (Integer)processEngine.getRuntimeService()
    .getVariable(execution2.getId(), "汇总当日销售额");
    System.out.println("给老总发送短信,金额是:"+value);
    processEngine.getRuntimeService()
    .signal(execution2.getId());

现在,我们来看完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 启动流程实例+设置流程变量+向后执行一步
*/
@Test
public void startProcessInstance() {
// 流程定义的key
String processDefinitionKey = "receiveTask";
ProcessInstance processInstance = processEngine.getRuntimeService()
.startProcessInstanceByKey(processDefinitionKey);
System.out.println("流程实例ID: " + processInstance.getId());
System.out.println("流程定义ID: " + processInstance.getProcessDefinitionId());
/*使用流程变量设置当日销售额,用来传递业务参数*/
/*查询执行对象id*/
Execution execution1 = processEngine.getRuntimeService()
.createExecutionQuery() // 使用流程实例Id查询
.processInstanceId(processInstance.getId())
// 当前活动的Id,对应receiveTask.bpmn文件中的活动节点id的属性值
.activityId("receivetask1")
.singleResult();
processEngine.getRuntimeService()
.setVariable(execution1.getId(), "汇总当日销售额", 21000);
/*向后执行一步,使得流程继续执行*/
processEngine.getRuntimeService()
.signal(execution1.getId());
/*从流程变量中获取汇总当日销售额的值*/
/*查询执行对象id*/
Execution execution2 = processEngine.getRuntimeService()
.createExecutionQuery() // 使用流程实例Id查询
.processInstanceId(processInstance.getId())
// 当前活动的Id,对应receiveTask.bpmn文件中的活动节点id的属性值
.activityId("receivetask2")
.singleResult();
Integer value = (Integer)processEngine.getRuntimeService()
.getVariable(execution2.getId(), "汇总当日销售额");
System.out.println("给老总发送短信,金额是:"+value);
processEngine.getRuntimeService()
.signal(execution2.getId());
}

执行代码,得到如下结果

流程实例ID: 5001
流程定义ID: receiveTask:1:4904
给老总发送短信,金额是:21000

这样,这个汇总当日销售额,给老总发短信的流程就结束了。

总结

最后,我们总结一下:

  1. 在接收任务创建后,意味着流程会进入等待状态, 直到引擎接收了一个特定的消息, 再触发流程穿过接收任务继续执行。
  2. 接收任务一般适合机器自动完成,但需要耗费一定时间的工作,向后推移流程,可以调用runtimeService.signal(executionId),传递接收执行对象的id