一个流程实例包含所有的运行节点,可以利用这个对象获取当前流程实例的进度信息。

Activiti流程和业务关系:

流程定义部署在acti后,就可以在系统中通过activiti去管理该流程的执行,执行流程表示流程的一次执行。
比如部署系统出差流程后,入股哦某个用户要申请出差这时就需要执行这个流程,如果另外一个用户也要申请出差则也需要执行该流程,互不影响。
启动流程实例时,指定的businesskey,就会在act_ru_exection#流程实例的执行表中存储businesskey
businesskey:业务标识,主键,业务标识和流程实例一一对应。业务标识来源于业务系统。存储业务标识就是根据业务标识来关联查询业务系统的数据。
比如:出差流程启动一实例,就将出差单id作为业务表示存储到acti表中,将查询acti的流程实例信息就可以获取出差单的id从而关联查询业务系统数据库得到出差单信息。
- /**
- * 添加业务Key到Activiti表
- */
- @Test
- public void addBusinessKey() {
- //获取流程引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取RuntimeService
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //启动流程的过程中,添加BussinessKey
- //参数:流程定义的key;businessKey,存出差单的id
- ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection", "1001");
- //输出
- System.out.println("businessKey=" + instance.getBusinessKey());
- }

全部流程实例挂起,将不允许启动新的流程实例,同时该流程定义下所有的流程实例将全部暂停执行。
2.1固定分配
在业务流程建模时指定固定的任务负责人

2.1表达式分配
由于固定分配方式,任务只管一步一步执行,执行到每一个任务将按照bpmn的配置去分配任务负责人。
UEL表达式:activiti使用UEL表达式

编写代码配置负责人
- /**
- * 启动流程实例
- */
- @Test
- public void testStartProcess() {
- //1.创建ProcessEngine
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //2.获取Runtimeservice
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //设定assignee的值,用来替换uel表达式
- HashMap
assigneeMap = new HashMap(); - assigneeMap.put("assignee0", "创建人");
- assigneeMap.put("assignee1", "经理");
- assigneeMap.put("assignee2", "总经理");
- assigneeMap.put("assignee3", "财务");
- //3.根据流程定义的id启动流程‘
- ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection1", assigneeMap);
- //4.输出内容
- System.out.println("流程定义id:" + instance.getProcessDefinitionId());
- System.out.println("流程实例id:" + instance.getId());
- System.out.println("当前活动id:" + instance.getActivityId());
- }
2.3监听器分配
可以使用监听器来完成很多Activiti流程的业务。流程设计时就不需要指定assignee。任务监听器是发生对应的任务相关事件时执行自定义java逻辑或表达式。
Event的选项包含:
Create:任务创建后触发
Assignment:任务分配后触发
Delete:任务完成后触发
All:所有事件发生都触发
创建demo:08-使用监听器设置负责人_哔哩哔哩_bilibili
2.4查询任务负责人的待办任务
见入门查询方法。
2.5关联businessKey
需求:在activiti实际应用时,查询代办任务可能要显示出业务系统的相关信息。
比如:查询待审批出差任务列表需要将出差单的日期,出差天数等信息显示。但是这些信息在业务系统中存在,而没有在activiti数据库中,所以无法通过activiti的api查询到出差信息
实现:在查询待办任务时,通过BusinessKey(业务标识)关联查询业务系统的出差单表,查询。
- /**
- * 获取任务负责人待办任务businessKey
- */
- @Test
- public void findProcessInstance() {
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = processEngine.getTaskService();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- Task task = taskService.createTaskQuery()
- .processDefinitionKey("testListener")
- .taskAssignee("创建人")
- .singleResult();
- String processDefinitionId = task.getProcessDefinitionId();
- ProcessInstance instance = runtimeService.createProcessInstanceQuery()
- .processDefinitionId(processDefinitionId)
- .singleResult();
- String businessKey = instance.getBusinessKey();
- System.out.println("businessKey=" + businessKey);
- }
在实际集中完成前需要校验负责人权限
- /**
- * 办理个人任务
- */
- @Test
- public void completTaskByCharge(){
- String taskId = "1005";
- String assingee = "经理";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = processEngine.getTaskService();
- //完成任务前,需校验该负责人可以完成当期任务
- //校验方法:根据任务id和负责人查询当前任务,如果查到该用户有权限,就完成
- Task task = taskService.createTaskQuery()
- .taskId(taskId)
- .taskAssignee(assingee)
- .singleResult();
- if(task!=null){
- taskService.complete(taskId);
- System.out.println("任务完成");
- }
- }

3.1流程变量
流程运转需要流程变量,业务系统和acti结合时也需要流程变量,流程变量就是acti在管理工作流时根据管理需要而设置的变量。
比如:出差申请流程流转时如果出差天数大于3天则由总经理审核,否则由人事直接审核,出差天数就可以设置为流程变量,在流程流转中使用。
注意:虽然流程变量中可以存储业务数据可以通过acti的api查询流程变量从而实现查询业务数据,但是不建议这样,因为业务数据查询由业务系统负责,acti设置流程变量是为了流程执行需要而创建。
3.2流程变量类型
如果将pojo存储到流程变量中,必须实现序列化接口serializable,为了防止由于新增字段无法反序列化,需要生成SerialVersionUID。
3.3流程变量作用域
可以是一个流程实例或一个任务。或一个执行实例。
Globa变量
流程变量的默认作用域是流程实例。当一个流程变量的作用域为流程实例时,成为global变量。
注意:Global变量:userId(变量名),创建人(变量值)
3.4流程变量使用方法
1.在属性上使用UEL表达式:可在assignee处设置,比如${assignee}
2.在连线上使用UEL表达式:可在连线上设置,决定流程走向,比如${price<100}
3.5使用Global变量控制流程
需求:员工创建出差单,由部门经理审核通过后出差三天以下由财务直接审批,3天上由总经理审批,再由财务审批。

流程定义:

设置global流程变量:
1.创建pojo对象。
2.启动流程时设置变量
- //启动流程设置流程变量
- @Test
- public void testStartProcess() {
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
- String key = "myEvection2";
- //设置流程变量
- Evection evection = new Evection();
- HashMap
variables = new HashMap(); - evection.setNum(2d); //设置出差日期
- variables.put("evection", evection); //把流程变量的pojo放入map
- variables.put("assignee0", "创建人");
- variables.put("assignee1", "部门经理");
- variables.put("assignee2", "总经理");
- variables.put("assignee3", "财务");
-
- ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, variables);
- System.out.println(instance.getId());
- }
3.任务办理时设置变量
注意:通过当前任务设置,需指定当前任务id,如果不存在则抛异常。任务办理时可map设置多个变量。
- //测试任务办理时添加流程变量
- @Test
- public void testCompletTask2() {
- String key = "myEvection2";
- String assignee = "创建人";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //设置流程变量
- Evection evection = new Evection();
- evection.setNum(2d);
- HashMap
map = new HashMap(); - map.put("evection", evection);
-
- TaskService taskService = processEngine.getTaskService();
- Task task = taskService.createTaskQuery()
- .processDefinitionKey(key)
- .taskAssignee(assignee)
- .singleResult();
- if (task != null) {
- taskService.complete(task.getId(),map); //根据任务id完成任务,在完成任务时设置流程变量
- }
- }
4.通过当前流程实例设置:通过流程实例id设置全局变量,该流程实例必须未执行完成。
注意:executionId必须当前未结束流程实例的执行id,通常此id设置流程实例的id也可通过runtimeService.getVariable()获取变量。
- //通过当前流程实例设置
- @Test
- public void setGlobalVariableByExectionId(){
- String exectionId = "";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- RuntimeService runtimeService = processEngine.getRuntimeService();
-
- Evection evection = new Evection();
- evection.setNum(3d);
-
- runtimeService.setVariable(exectionId,"evection",evection); //通过流程实例id设置流程变量
- // runtimeService.setVariable(exectionId, variables); //一次设置多个变量
- }
5.通过当前任务设置
注意:任务id必须是当前待办id,act_ru_task存在
- //通过当前任务设置
- @Test
- public void setGlobalVariableByTaskId(){
- String taskId = "4102";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = processEngine.getTaskService();
- Evection evection = new Evection();
- taskService.setVariable(taskId,"evection",evection);
- }
3.6设置local流程控制
略
4.1需求:在流程定义在任务节点的assignee固定设置任务负责人,在流程定义时将参与者固定设置在.bpmn文件中,如果临时任务负责人变更则需要修改流程定义,系统可扩展性差。
针对这种情况可以设置多个候选人。
4.2设置任务候选人

4.3组任务办理流程
a.查询组任务
指定候选人,查询该候选人当前待办。候选人不能立即办理。
b.拾取组任务
该组任务的所有候选人都能拾取。将候选人的组任务,变成个人任务。原来候选人就变成了该任务的负责人。
如果拾取后不想办理该任务?需将已经拾个人任务归还组里面,将个人任务变成组任务。
c.查询个人任务
d.办理个人任务
查询组任务
- //查询组任务
- @Test
- public void findGroupTaskList(){
- String key = "testCandidate";
- String candidateUser = "候选人";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = processEngine.getTaskService();
- List
taskList = taskService.createTaskQuery() - .processDefinitionKey(key)
- .taskCandidateUser(candidateUser) //根据候选人查询任务
- .list();
- for (Task task : taskList) {
- System.out.println("流程实例id" + task.getProcessDefinitionId());
- System.out.println("任务id" + task.getId());
- System.out.println("任务负责人" + task.getAssignee());
- }
- }
拾取任务
- //拾取任务
- @Test
- public void claimTask() {
- ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = defaultProcessEngine.getTaskService();
- String taskId = "6001";
- String userId = "候选人";
- //拾取任务,都可以拾取,需校验资格
- Task task = taskService.createTaskQuery()
- .taskId(taskId)
- .taskCandidateUser(userId)
- .singleResult();
- if (task != null) {
- taskService.claim(taskId, userId);
- System.out.println("拾取成功");
- }
- }
归还任务
- //归还任务
- @Test
- public void assigneeToGroupTask() {
- ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = defaultProcessEngine.getTaskService();
- String taskId = "6001";
- String assignee = "负责人";
- //根据key和负责人查询
- Task task = taskService.createTaskQuery()
- .taskId(taskId)
- .taskAssignee(assignee)
- .singleResult();
- if (task != null) {
- taskService.setAssignee(taskId, null);
- System.out.println("拾取成功");
- }
- }
任务交接
- //任务交接
- @Test
- public void setAssigneeToCandidateUser() {
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- TaskService taskService = processEngine.getTaskService();
- String taskId = "6001";
- String userId = "负责人";
- String candidateUser = "其他候选人";
- //校验userId是都是taskid的负责人,如果是负责人才可以归还组任务
- Task task = taskService
- .createTaskQuery()
- .taskId(taskId)
- .taskAssignee(userId)
- .singleResult();
- if (task != null) {
- taskService.setAssignee(taskId, candidateUser);
- }
- }
5.1排他网关

5.2并行网关



并行网关代码测试:08-并行网关流程定义-测试_哔哩哔哩_bilibili
5.3包含网关


包含网关测试:11-包含网关测试_哔哩哔哩_bilibili
5.4事件网关