前面介绍了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. UVa 231 - Testing the CATCHER

    题目大意:一种拦截导弹能拦截多枚导弹,但是它在每次拦截后高度不会再升高,给出导弹的序列,问最多能拦截多少枚导弹? 最长递减子序列问题. #include <cstdio> #include ...

  2. [Angular Tutorial] 5-Filtering Repeaters

    在上一步中,我们花了很大功夫来布局应用的基础,所以我们现在做点简单点的吧!我们将会添加一个全文本搜索框(没错,这很简单). ·我们的应用现在会有一个搜索框,注意页面中手机列表的改变取决于用户在搜索框键 ...

  3. 我对CSS中的BFC的理解

       1.什么是BFC 其实在老师让我们写这篇叫BFC的时候,我跟本不知道有什么BFC的东西. 后来,我找了一些资料,知道了,BFC是Block Formatting Context (块级格式化上下 ...

  4. 与文件上传到的三个类:FileItem类、ServletFileUpload 类、DiskFileItemFactory类

    文件上传: ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中, 在使用ServletFileUpload对象解析请求时需要根据DiskFi ...

  5. Stanford机器学习课程之一——引言

    Andrew Ng的Machine Learning课程,在网易公开课上有中文版视频http://v.163.com/special/opencourse/machinelearning.html,六 ...

  6. Maven与Antx(整理)

    http://blog.csdn.net/ghost_t/article/details/5709640 一.Maven与Antx概况: Antx简介   在讲为什么使用maven之前我想说一下,an ...

  7. PayPal为什么从Java迁移到Node.js

    前言 大家都知道PayPal是另一家迁移到Node.js平台的大型公司,Jeff Harrell的这篇博文 Node.js at PayPal  解释了为什么从Java迁移出来的原因: 开发效率提高一 ...

  8. Weblogic常见故障常:JDBC Connection Pools

    http://blog.csdn.net/woshixuye/article/details/24122579 有些时候是数据库连接池出现了问题,测试的时候显示没有连接池了,重启WebLogic都不行 ...

  9. Bootstrap入门(七)组件1:字体图标

    Bootstrap入门(七)组件1:字体图标   包括200个来自 Glyphicon Halflings 的字体图标,允许 Bootstrap 免费使用. 部分可用图标截图: 所有图标都需要一个基类 ...

  10. JS日期时间加减实现

    首先,上代码 var diffDate = function(date, diff) { return new Date( Date.UTC( date.getUTCFullYear(), date. ...