连线
流程图绘制
condition:为流程变量的设置
路程部署
/**
* 部署流程
*/
private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
@Test
public void deployProcess(){
//得到RepositoryService
RepositoryService service = processEngine.getRepositoryService();
//部署
InputStream isBpmn = this.getClass().getResourceAsStream("/SequenceFlow.xml");
InputStream isPng = this.getClass().getResourceAsStream("/SequenceFlow.png");
Deployment deployment = service.createDeployment().name("连线")//部署的名称
.addInputStream("SequenceFlow.bpmn", isBpmn)//设置;流程图的xml文件
.addInputStream("SequenceFlow.png", isPng)//设置流程图的PNG文件
.deploy();//确定
/**
* act_re_deployment:流程部署表
* act_re_model:
* act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
* act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
* act_ge_property:系统内置表存放activiti的版本和自动增长的字段
*/
System.out.println("流程部署成功:");
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
}
流程启动
/**
* 启动流程
*/
@Test
public void startProcess(){
/**
* act_ru_execution:流程实例ID,里面有流动ID,流程定义ID
* act_ru_identitylink:当前流程节点的办理人信息
* act_ru_task:当前正在执行的流程任务表
* act_ru_variable:执行的流程变量
*/
//得到流程运行服务
RuntimeService runtimeService = this.processEngine.getRuntimeService();
//启动流程、
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("SequenceFlow");
System.out.println("流程启动成功");
System.out.println("流程实例ID:" + processInstance.getId());
}
查询个人任务
/**
* 查询个人任务
*/
@Test
public void findUserTask(){
//任务办理人
String assignee = "王五";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
//创建一个查询
List<Task> list = taskService.createTaskQuery().taskId("15005").list();
for(Task task : list){
System.out.println("任务ID:" + task.getId());
System.out.println("任务办理人:" + task.getAssignee());
System.out.println("流程实例ID:" + task.getExecutionId());
System.out.println("任务名称:" + task.getName());
System.out.println("流程定义ID:" + task.getProcessDefinitionId());
System.out.println("流程:" + task.getProcessInstanceId());
System.out.println("任务创建时间:" + task.getCreateTime());
}
}
使用流程变量完成任务(重要)
/**
* 使用流程变量完成任务
*/
@Test
public void completeTaskWithVariables(){
String taskId = "15005";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
Map<String,Object> variables = new HashMap<>();
variables.put("message","重要");
//通过流程变量控制连线的走向
taskService.complete(taskId,variables);
System.out.println("任务完成");
}
完成任务
/**
* 完成任务
*/
@Test
public void completeTask(){
String taskId = "17503";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
//通过流程变量控制连线的走向
taskService.complete(taskId);
System.out.println("任务完成");
}
总结:
1、一个活动中可以指定一个或多个SequenceFlow(Start中有一个,End中没有)
- 开始活动中有一个SequenceFlow
- 结束活动中没有SequenceFlow
- 其他活动中有1条或多条SequenceFlow
2、如果只有一个,则可以不使用流程变量设置codition的名称
如果有多个,则需要使用流程变量设置codition的名称,message表示流程变量名称,'不重要’表示流程变量的值,${}中间的内容要使用boolean类型的表达式,用来判断应该执行的连线
排他网关(ExclusiveGateWay)
报销
业务员提交报销申请
如果金额小于500 可以直接由财务审批
如果金额大于等于500 小于1000由部门经理审批
如果金额大于等于1000 由总经理审批
流程图
其中boolean表达式使用和连线中相似
默认的流程无须设定,我被坑了
流程部署
/**
* 部署流程
*/
private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
@Test
public void deployProcess(){
//得到RepositoryService
RepositoryService service = processEngine.getRepositoryService();
//部署
InputStream isBpmn = this.getClass().getResourceAsStream("/ExclusiveGateWay.xml");
InputStream isPng = this.getClass().getResourceAsStream("/ExclusiveGateWay.png");
Deployment deployment = service.createDeployment().name("排他网关")//部署的名称
.addInputStream("ExclusiveGateWay.bpmn", isBpmn)//设置;流程图的xml文件
.addInputStream("ExclusiveGateWay.png", isPng)//设置流程图的PNG文件
.deploy();//确定
/**
* act_re_deployment:流程部署表
* act_re_model:
* act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
* act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
* act_ge_property:系统内置表存放activiti的版本和自动增长的字段
*/
System.out.println("流程部署成功:");
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
}
启动流程(变量设置)
/**
* 启动流程
*/
@Test
public void startProcess(){
/**
* act_ru_execution:流程实例ID,里面有流动ID,流程定义ID
* act_ru_identitylink:当前流程节点的办理人信息
* act_ru_task:当前正在执行的流程任务表
* act_ru_variable:执行的流程变量
*/
//得到流程运行服务
RuntimeService runtimeService = this.processEngine.getRuntimeService();
//启动流程 需要给出排他网关的条件
Map<String,Object> variables = new HashMap<>();
variables.put("money",1200);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ExclusiveGateWay",variables);
System.out.println("流程启动成功");
System.out.println("流程实例ID:" + processInstance.getId());
}
查询个人任务
/**
* 查询个人任务
*/
@Test
public void findUserTask(){
//任务办理人
String assignee = "王五";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
//创建一个查询
List<Task> list = taskService.createTaskQuery().taskId("2507").list();
for(Task task : list){
System.out.println("任务ID:" + task.getId());
System.out.println("任务办理人:" + task.getAssignee());
System.out.println("流程实例ID:" + task.getExecutionId());
System.out.println("任务名称:" + task.getName());
System.out.println("流程定义ID:" + task.getProcessDefinitionId());
System.out.println("流程:" + task.getProcessInstanceId());
System.out.println("任务创建时间:" + task.getCreateTime());
}
}
完成任务
/**
* 完成任务
*/
@Test
public void completeTask(){
String taskId = "2507";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
//通过流程变量控制连线的走向
taskService.complete(taskId);
System.out.println("任务完成");
}
总结:
- 一个排他网关对应一个以上的顺序流
- 由排他网关流出的顺序流都有个coditionExpression元素,在内部维护返回boolean类型的决策结果
- 决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出
- 如果没有任何一个出口符合条件,则抛出异常
- 使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有条件符合的条件,则以默认的连线离开
并行网关(ParallelGateWay)
使用场景
购物
买家付款 收货
卖家发货 收款
流程图
部署流程
/**
* 部署流程
*/
private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
@Test
public void deployProcess(){
//得到RepositoryService
RepositoryService service = processEngine.getRepositoryService();
//部署
InputStream isBpmn = this.getClass().getResourceAsStream("/ParallelGateWay.xml");
InputStream isPng = this.getClass().getResourceAsStream("/ParallelGateWay.png");
Deployment deployment = service.createDeployment().name("并行网关")//部署的名称
.addInputStream("ParallelGateWay.bpmn", isBpmn)//设置;流程图的xml文件
.addInputStream("ParallelGateWay.png", isPng)//设置流程图的PNG文件
.deploy();//确定
/**
* act_re_deployment:流程部署表
* act_re_model:
* act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
* act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
* act_ge_property:系统内置表存放activiti的版本和自动增长的字段
*/
System.out.println("流程部署成功:");
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
}
启动流程
/**
* 启动流程
*/
@Test
public void startProcess(){
/**
* act_ru_execution:流程实例ID,里面有流动ID,流程定义ID
* act_ru_identitylink:当前流程节点的办理人信息
* act_ru_task:当前正在执行的流程任务表
* act_ru_variable:执行的流程变量
*/
//得到流程运行服务
RuntimeService runtimeService = this.processEngine.getRuntimeService();
//启动流程、
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ParallelGateWay");
System.out.println("流程启动成功");
System.out.println("流程实例ID:" + processInstance.getId());
}
查询个人任务
/**
* 查询个人任务
*/
@Test
public void findUserTask(){
//任务办理人
String assignee = "买家";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
//创建一个查询
List<Task> list = taskService.createTaskQuery().taskId("15005").list();
for(Task task : list){
System.out.println("任务ID:" + task.getId());
System.out.println("任务办理人:" + task.getAssignee());
System.out.println("流程实例ID:" + task.getExecutionId());
System.out.println("任务名称:" + task.getName());
System.out.println("流程定义ID:" + task.getProcessDefinitionId());
System.out.println("流程:" + task.getProcessInstanceId());
System.out.println("任务创建时间:" + task.getCreateTime());
}
}
完成任务
/**
* 完成任务
*/
@Test
public void completeTask(){
String taskId = "17503";
//得到任务的Service
TaskService taskService = this.processEngine.getTaskService();
//通过流程变量控制连线的走向
taskService.complete(taskId);
System.out.println("任务完成");
}
总结:
-
一个流程中流程实例只有1个,执行对象有多个
-
并行网关的功能是基于进入和外出的顺序流的
-
分支(fork)
并行后的所有外出顺序流,为每个顺序流都创建一个并发分支
汇聚(join)
所有到达并行网关,在此等待的进入分支,直到所有进入顺序流的分支都到达以后,流程就会通过汇聚网关
-
并行网关的进入和外出都是使用相同节点标识
-
如果同一个并行网关有多个进入和多个外出顺序流,她就同时具有分支和汇聚功能。这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支
-
并行网关不会解析条件,即使顺序流中定义了条件,也会被忽略。
-
并行网关不需要是平衡的(比如,对应并行网关的进入和外出节点数目不一定相等)。
接收活动(receiveTask)
接收活动是一个简单任务,他会等待对应消息的到达。当前,官方只实现了这个任务的java语义。当流程到达接收任务,流程状态会保存到数据库中。
在任务创建后,意味着流程会进入等待状态,直到引擎接收了一个特定的消息,这会触发流程穿过接收任务继续执行。
流程图
部署流程
/**
* 部署流程
*/
private ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("/activiti.cfg.xml").buildProcessEngine();
@Test
public void deployProcess(){
//得到RepositoryService
RepositoryService service = processEngine.getRepositoryService();
//部署
InputStream isBpmn = this.getClass().getResourceAsStream("/ReceiveTask.xml");
InputStream isPng = this.getClass().getResourceAsStream("/ReceiveTask.png");
Deployment deployment = service.createDeployment().name("接收活动")//部署的名称
.addInputStream("ReceiveTask.bpmn", isBpmn)//设置;流程图的xml文件
.addInputStream("ReceiveTask.png", isPng)//设置流程图的PNG文件
.deploy();//确定
/**
* act_re_deployment:流程部署表
* act_re_model:
* act_re_procdef:流程定义表,它和部署表里面的数据是一一对应的
* act_ge_bytearray:二进制文件存放表,和部署表和定义表是2-1关系
* act_ge_property:系统内置表存放activiti的版本和自动增长的字段
*/
System.out.println("流程部署成功:");
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称:" + deployment.getName());
System.out.println("部署时间:" + deployment.getDeploymentTime().toLocaleString());
}
启动流程
/**
* 启动流程
*/
@Test
public void startProcess(){
RuntimeService runtimeService = this.processEngine.getRuntimeService();
//根据了;流程定义的KEY去启用流程
String processDefinitionKey = "ReceiveTask";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
System.out.println("启动成功");
//查询当前流程实例
String id = processInstance.getId();
//调用某个方法去查询数据库里面的汇总信息
Double money = 10000.0;
Execution execution = processEngine.getRuntimeService()
.createExecutionQuery()//创建执行对象查询
.processInstanceId(id)//创建流程实例ID查询
.activityId("ReceiveTask1")//当前活动的id
.singleResult();
System.out.println(execution.getActivityId());
runtimeService.setVariable(execution.getId(),"money",money);
//把流程向下走一步
runtimeService.signalEventReceived(execution.getId());
//接收到这个任务
/**
* 查询执行对象ID
*/
Execution execution1 = processEngine.getRuntimeService()
.createExecutionQuery()
.processInstanceId(id)
.activityId("ReceiveTask2")
.singleResult();
//取出流程变量
Object money1 = runtimeService.getVariable(execution1.getId(), "money");
//调用短信或其他去向总经理发送信息
System.out.println("发送信息:" + money1);
//如果发送成功,再把流程向下走一步
runtimeService.signalEventReceived(execution1.getId());
}
说明:
当前任务(一般指机器自动完成,但需要耗费一定时间的工作)完成后,向后推移流程,可以调用RuntimeService向下执行,传递接收执行对象的id