前面介绍了Activiti工作流的基本操作,但是在实际应用过程中,往往不满足项目需求,因此还需要了解一些其他的功能比如:连线、排他网关、并行网管、流程变量、个人任务及组任务的三种发布方式。

下面将介绍Activiti工作流中的连线操作

首先需要构建一个流程实例并且部署到项目中去


 可以看出这个流程实例和之前的有一些区别,就是连线上多了一下文字,要想让流程引擎通过连线来辨别走哪个流程需要在连线上加上对应的条件,比如${message=="不紧急"},然后再在完成任务的时候讲该信息封装到map中并传递给流程引擎

  @Test
public void compileTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //任务ID
String taskID = "302"; //获得任务服务
TaskService taskService = processEngine.getTaskService(); Map<String, Object> map = new HashMap<String, Object>();
map.put("message", "不紧急"); taskService.complete(taskID, map);
}

这样流程引擎就会将该任务分配给部门主管,通过对连线的设置可以手动的将任务分配给指定的人,但是在实际应用过程中,往往还需要一个默认执行的流程,这时候就需要排他网关

首先构建一个新的流程实例并且部署上去


 在排他网关中,我们需要设置一个Default flow,里面填上需要默认执行连线的ID,且其它连线需要设置对应的Condition,在流程任务执行任务的过程中,当检测到没有一条连线符合我们需要执行的流程的条件时,排他网关会默认的将该任务分配给默认的连线,这里有几点需要注意:

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

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

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

接下来是并行网关,首先创建流程实例并且部署到项目上


 当该流程启动之后,观察数据库中的表的数据

首先观察ACT_RU_TASK表,这里面是我们需要执行的task


 然后再看ACT_RU_EXECUTION表,这张表很重要,体现了并行网关的功能


 接下来我们先完成付款和收款任务,然后再观察这两张表里面的数据


 

 可以看见在ACT_RU_TASK表中已经少了一项数据,但是在ACT_RU_EXECUTION表中数据还没有变,接下来再去完成发货和收获任务,然后再观察着两张表


 

 可以看见这两张表中都已经没有了任何数据,尤其是ACT_RU_EXECUTION表,这张表只有当并行网关中的所有任务都执行完毕之后数据才会消失。

并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略,同时并行网关是不需要平衡的。

然后再看流程变量,流程变量相对简单,只需要写两个方法,一个方法设置流程变量,一个方法获取流程变量即可,只需要注意一点,流程变量可以设置和获取一个实体类对象,这里直接贴出代码

@Test
public void setVariables(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); String assigneeUser = "Asen";
String instanceId = "101"; TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery()
.taskAssignee(assigneeUser)
.processInstanceId(instanceId)
.singleResult(); Person person = new Person("Meixi", 30, "Asen3245243", "13090908080"); taskService.setVariable(task.getId(), "取钱人", "Ronaldo");
taskService.setVariableLocal(task.getId(), "金额", "10000");
taskService.setVariable(task.getId(), "取钱人信息", person); } @Test
public void getVariables(){
String assignUser = "Asen";
String instanceId = "101"; ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery()
.taskAssignee(assignUser)
.processInstanceId(instanceId)
.singleResult(); String user = (String) taskService.getVariable(task.getId(), "取钱人");
String money = (String) taskService.getVariable(task.getId(), "金额");
Person personMessage = (Person) taskService.getVariable(task.getId(), "取钱人信息"); System.out.println("user:" + user + " money:" + money + " personMessage:" + personMessage);
}

最后就是个人任务及组任务的三种分配方式,其中个人任务和组任务的分配方式大同小异,首先是个人任务的分配,第一种就是直接Assign给一个人名(字符串)


 第二种就是封装成一个map传递给流程引擎

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
@Test
public void testTask() throws Exception { InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
processEngine.getRepositoryService()//
.createDeployment()//
.addInputStream("userTask.bpmn", inputStreamBpmn)//
.addInputStream("userTask.png", inputStreamPng)//
.deploy(); Map<String, Object> variables = new HashMap<String, Object>();
variables.put("userID", "Ronaldo");
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceByKey("taskProcess",variables);
}

第三种分配方式使用类,这时候不需要指定办理人,直接添加一个类即可


 

 

 此时的bpmn_xml文件内容已经发生变化

<userTask id="usertask1" name="付款" activiti:assignee="Asen">
<extensionElements>
<activiti:taskListener event="create" class="com.asen.entity.Person"></activiti:taskListener>
</extensionElements>
</userTask>

最后我们需要手动添加一个类去实现TaskListener接口,并且重写notify方法,在该方法中我们需要去指定个人任务

@Override
public void notify(DelegateTask delegateTask) {
String assignee = "Ronaldo";
//指定个人任务
delegateTask.setAssignee(assignee);
}

然后就可以去查询了

@Test
public void findMyTaskList(){
String userId = "Ronaldo";
List<Task> list = processEngine.getTaskService()//
.createTaskQuery()//
.taskAssignee(userId)//指定个人任务查询
.list();
for(Task task:list ){
System.out.println("id="+task.getId());
System.out.println("name="+task.getName());
System.out.println("assinee="+task.getAssignee());
System.out.println("createTime="+task.getCreateTime());
System.out.println("executionId="+task.getExecutionId()); }
}

组任务的三种分配方式就太过详细的写出来了

分配方式一:


 分配方式二:

//部署流程定义,启动流程实例
@Test
public void testTask() throws Exception {
// 1 发布流程
InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
processEngine.getRepositoryService()//
.createDeployment()//
.addInputStream("userTask.bpmn", inputStreamBpmn)//
.addInputStream("userTask.png", inputStreamPng)//
.deploy();
// 2 启动流程
//启动流程实例,同时设置流程变量,用来指定组任务的办理人
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("userIDs", "小红,小亮,小明");
ProcessInstance pi = processEngine.getRuntimeService()//
.startProcessInstanceByKey("taskProcess",variables);
System.out.println("pid:" + pi.getId());
}

分配方式三:

同样添加一个类,但是实现方法有所区别

public class TaskListenerImpl implements TaskListener {

    /**指定个人任务和组任务的办理人*/
@Override
public void notify(DelegateTask delegateTask) {
String userId1 = "小红";
String userId2 = "小亮";
//指定组任务
delegateTask.addCandidateUser(userId1);
delegateTask.addCandidateUser(userId2);
} }

最后补上一些很常用的方法

//可以分配个人任务从一个人到另一个人(认领任务)
@Test
public void setAssigneeTask(){
//任务ID
String taskId = "3408";
//指定认领的办理者
String userId = "Meixi";
processEngine.getTaskService()//
.setAssignee(taskId, userId);
} //将组任务分配给个人任务(认领任务)
@Test
public void claimTask(){
String taskId = "4008";
//个人任务的办理人
String userId = "小明";
processEngine.getTaskService().claim(taskId, userId);
} //可以分配个人任务回退到组任务,(前提之前是个组任务)
@Test
public void setAssigneeTask(){
//任务ID
String taskId = "4008";
processEngine.getTaskService()//
.setAssignee(taskId, null);
} //向组任务中添加成员
@Test
public void addUser(){
String taskId = "4008";
String userId = "小红";
processEngine.getTaskService().addCandidateUser(taskId, userId);
} //向组任务中删除成员
@Test
public void removeUser(){
String taskId = "4008";
String userId = "小亮";
processEngine.getTaskService().deleteCandidateUser(taskId, userId);
}

Activiti工作流(二)之常用操作的更多相关文章

  1. .Net Excel操作之NPOI(二)常用操作封装

    一.Excel数据导出常用操作 1.指定表头和描述 2.指定数据库中读出的数据集合 二.ExcelExport封装 /// <summary> /// Excel常用的表格导出逻辑封装 / ...

  2. 从零开始学Linux[二]:常用操作:用户组、进程、网络、ssh

    摘要:Linux基础学习:创建用户组和用户.软件包管理.磁盘管理.进程管理.前后台进程的切换.网络配置.浏览网页.远程登录ssh 第一节,主要介绍一些简单命令,这节介绍一些日常操作. 1.创建用户组和 ...

  3. RMAN备份与恢复(二)--常用操作学习

    (1)连接目标数据库 在RMAN中可以建立与目标数据库或恢复目录数据库的连接.与目标数据库连接时,用户须具有sysdba系统权限,以保证可以进行数据库的备份.修复与恢复工作. 可以在操作系统命令提示符 ...

  4. python接口自动化测试二:常用操作

    url = '接口地址' r = requests.get(url)                      # 发送get请求 print(r.status_code)               ...

  5. Activiti工作流框架学习笔记(二)之springboot2.0整合工作流Activiti6.0

    以前在工作当中做过不少与工作流Activiti有关的工作,当时都是spring集成activiti5.22的项目,现在回过头去看,其实版本已经稍微老了,因此,基于先前的工作经验,决定用较新版本的技术来 ...

  6. Redis系列(二):常用操作

    一.数据类型 如果学过数据结构就会知道,操作往往是在特定的数据结构上的,不同的数据结构就会有不同的操作,Redis支持以下的数据类型: 字符串(Strings),列表(Lists),集合(Sets), ...

  7. Hdfs常用操作

    一.linux rm是删除,不是del 二.常用操作 package hdfs; import java.io.FileInputStream; import java.io.FileNotFound ...

  8. [Python] re正则表达式指南以及常用操作

    一.语法 1. 使用正则表达式进行匹配的流程 2. Python支持的正则表达式元字符和语法 参考: AstralWind的Python正则表达式指南 官方文档:7.2. re — Regular e ...

  9. Linux 笔记 - 第十五章 MySQL 常用操作和 phpMyAdmin

    博客地址:http://www.moonxy.com 一.前言 前面几章介绍了 MySQL 的安装和简单的配置,只会这些还不够,作为 Linux 系统管理员,我们还需要掌握一些基本的操作,以满足日常管 ...

随机推荐

  1. IOS web app一些实用的属性设置

    IOS对safari私有的属性很多,虽然很多不为人知但是却很实用.掌握好这些属性对web app和混合app的开发会很有帮助. 1.format-detection[telephone=no] 是否自 ...

  2. OC纯代码全手工打造ScroolView实现翻页

    OC纯代码全手工打造ScroolView实现翻页 1. 概述 分为三部分: 上部标题ScrollView 下部内容ScrollView 上部当前页 标示线 2. 效果 上下两部分都随着手势的滑动一块滑 ...

  3. 解压文件--linux

    linux下不同的文件格式用不同的命令解压. 对于tar.gz文件,用以下命令. .tar.gz 和 .tgz解压:tar zxvf FileName.tar.gz压缩:tar zcvf FileNa ...

  4. DELPHI中MessageBox的用法

    MessageBox对话框 输入控件的   ImeName属性把输入法去掉就默认为英文输入了 MessageBox对话框是比较常用的一个信息对话框,其不仅能够定义显示的信息内容.信息提示图标,而且可以 ...

  5. pipe管道

    回顾: 进程间通信方式: 信号,管道 消息队列,共享内存,信号量 sokcet 信号: 本质就是软中断 signal(信号,函数指针); void func(int); kill(pid,signo) ...

  6. 完美解决夏天电脑cpu发烫问题

    最近有朋友跟我反馈,说苹果电脑虽然好用,但是一直有一个问题困扰着他,就是电脑散热的问题.每到夏天的时候,电脑运转之后就会发烫,用的特别的不舒服. 相信用电脑的都会有这样的感受吧,更加相信你们都用过以下 ...

  7. Bootstrap入门(四)表格

    Bootstrap入门(四)表格 <table>标签 首先,引入bootstrap的css文件,然后表格内容放在一个class为table的<table>标签中(class=& ...

  8. Atom 编辑器系列视频课程

    此课程为 Atom 编辑器系列课程,主要介绍了 Atom 的高效开发技巧以及必备插件. 课程列表 Atom编辑器系列课程 #1 - Atom简介 Atom编辑器系列课程 #2 - 设置简介 Atom编 ...

  9. 我为什么不看好微信小程序

    我自认为对新技术还是比较有热情的,可对于小程序这个“新技术”,我却完全是被动的.去年9月份的时候,微信小程序开始内测,瞬间引爆朋友圈.知乎等一众分享平台.当时我大概了解了一下,觉得从技术角度上来说没啥 ...

  10. TimSort in Java 8

    在项目中使用了Collections.sort(list, comparator)对集合进行了排序,偶然间遇到异常IllegalArgumentException: "Comparison ...