Activiti工作流引擎学习(一)
1、部署对象和流程定义相关表:RepositoryService
act_re_deployment: 部署对象表:一次部署的多个文件的信息,对于不需要的流程可以删除和修改
act_re_procdef: 流程定义表:解析bpmn后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则进行的
act_ge_bytearray: 资源文件表
key和name为bpmn文件process节点的id和name的属性值
key属性用来区别不同的流程定义
带有特定key的流程定义第一次部署时,version为1,之后每次部署都会在当前版本号加1
id的生成规则:key+version+随机数
重复部署一次,deplymentId是一个自动生成的唯一数字,规则在act_ge_property表;
还会存储序列化的流程变量
act_ge_property: 主键生成策略表
1.1 部署流程定义:(classPath路径加载文件)
1)先获取流程引擎对象,在创建时会自动加载classPath下的activiti.cfg.xml
2)首先获得默认的流程引擎,通过流程引擎获取一个RepositoryService对象(仓库对象)
3)由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置
4)这是一个链式编程,在部署配置对象中设置显示名,上传流程规则文件
5)向数据库表中存放流程定义的规则消息
6)这一步在数据库中操作三张表:
act_re_deployment: 部署对象表
存放流程定义的显示名和部署时间,每部署一次增加一条记录
act_re_procdef: 流程定义表
存放流程定义的属性信息,部署每个新的流程定义都会在这张表增加一条记录,注意:当流程定义的key向同事,使用版本升级
act_ge_bytearray: 资源文件表
存储流程定义相关的部署信息,即流程定义文档的存放地,没部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片,(若部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都以二进制形式存储在数据库中。
1.2 部署流程定义:(zip)
将bpmn和png压缩成zip包,使用zip的输入流用作部署流程定义
1.3 删除流程定义
已经启动的流程不能删除,否则会抛异常;
若想删除已启动的流程,采取级联删除
1.4 流程定义不能修改
控制修改的方法:key相同,版本升级,再启动,执行最新版本
1.5 启动流程实例 RuntimeService
使用流程实例的key或Id启动,使用key默认启动最新版本
2、 流程实例
act_ru_execution:正在执行的执行对象表
如果是单例流程(没有分支和聚合),那么流程实例ID和执行对象ID是相同的;
一个流程中流程实例只有一个,执行对象可以存在多个(有分支和聚合);
流程结束后,流程实例会在正在执行的执行对象表中被删除
act_hi_procinst:流程实例的历史表 HistoryService
act_ru_task:正在执行的任务列表(只存userTask节点的数据)
act_hi_taskinst:任务历史表(只存userTask节点的数据)
act_hi_actinst:所有活动节点的历史表。
package com.controller; import java.util.List; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class FlowController { @Autowired
private ProcessEngine processEngine; /**
* 部署流程定义
* @return
*/
@RequestMapping("deployFlow")
public String deployFlow(){
//管理流程定义的service
RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment().name("helloword流程") //创建一个部署对象
.addClasspathResource("diagrams/helloword.bpmn") //从classPath中加载资源文件,一次只能加载一个
.addClasspathResource("diagrams/helloword.png")
.deploy();//完成部署 System.out.println(deployment.getId() + deployment.getName()); return deployment.getName();
} /**
* 启动流程实例
* @return
*/
@RequestMapping("startFlow")
public String startFlow(){ String processDefinitionKey = "helloword1"; //正在执行的流程实例和执行对象相关的service
RuntimeService runtimeService = processEngine.getRuntimeService(); //使用流程定义的key启动流程实例,key对应的是bpmn文件中的id,默认是最新版本的流程启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey); System.out.println(processInstance.getId() + processInstance.getProcessDefinitionId()); return processInstance.getProcessDefinitionId();
} /**
* 查询当前人的个人任务
* @return
*/
@RequestMapping("findPersonalTask")
public String findPersonalTask(){ String assignee = "李四"; List<Task> list = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee(assignee).list(); if(!CollectionUtils.isEmpty(list)){
for (Task task : list) {
System.out.println(task.getAssignee());
System.out.println(task.getId());
System.out.println(task.getName());
System.out.println(task.getExecutionId());
}
} System.out.println("****************"); return list.toString();
} /**
* 完成我的任务
* @return
*/
@RequestMapping("completePersonalTask")
public String completePersonalTask(){ String taskId = "5002"; processEngine.getTaskService().complete(taskId); return "完成任务" + taskId;
} }
3、 流程变量 (如请假天数、原因都是流程变量,流程变量的作用域范围只是对应一个流程实例,也就是各个流程实例的流程变量是不相互影响的,流程实例结束王城后流程变量还保存在数据库中)
作用:1. 用来传递业务参数
2.指定连线参数(同意和拒绝)
3.动态指定任务的办理人
package com.controller; import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class VariablesController { @Autowired
private ProcessEngine processEngine; /**
* 部署
* @return
*/
@RequestMapping("deploy")
public String deploy(){
InputStream bpmn = this.getClass().getResourceAsStream("/diagrams/Variables.bpmn");
InputStream png = this.getClass().getResourceAsStream("/diagrams/Variables.png"); Deployment deployment = processEngine.getRepositoryService().createDeployment().name("变量流程")
.addInputStream("Variables.bpmn", bpmn)//与资源文件名称要一致
.addInputStream("Variables.png", png)
.deploy(); System.err.println(deployment.getKey() + "---" + deployment.getName()); return deployment.getId(); } /**
* 启动流程实例
* @return
*/
@RequestMapping("startVar")
public String startFlow(){ String processDefinitionKey = "ProcessVariable"; //正在执行的流程实例和执行对象相关的service
RuntimeService runtimeService = processEngine.getRuntimeService(); //使用流程定义的key启动流程实例,key对应的是bpmn文件中的id,默认是最新版本的流程启动
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey); System.out.println(processInstance.getId() + processInstance.getProcessDefinitionId()); return processInstance.getProcessDefinitionId();
} /**
* 设置流程变量
* @return
*/
@RequestMapping("setVariables")
public String setVariables(){ TaskService taskService = processEngine.getTaskService(); String taskId ="17502"; //设置
taskService.setVariable(taskId, "请假天数", 3); Map<String, String> map = new HashMap<String, String>();
map.put("请假原因", "出去玩儿"); taskService.setVariables(taskId, map); //查询
List<String> list = new ArrayList<String>();
list.add("请假原因");
list.add("请假天数"); Map<String, Object> vMap = taskService.getVariables(taskId,list); System.err.println(vMap.toString()); return "设置流程变量成功!";
} /**
* 模拟设置和获取流程变量的场景
* @return
*/
public String setAndGetVariables(){ //与流程实例,执行对象
RuntimeService runtimeService = processEngine.getRuntimeService(); //与任务
TaskService taskService = processEngine.getTaskService(); /*表示使用执行对象ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)*/
//runtimeService.setVariable(executionId, variableName, value);
/*表示执行对象ID,和map集合设置流程变量,map集合的key是流程变量名称,value是变量值*/
//runtimeService.setVariables(executionId, variables);
/*表示使用任务ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)*/
//taskService.setVariable(taskId, variableName, value);
/*表示任务ID,和map集合设置流程变量,map集合的key是流程变量名称,value是变量值*/
//taskService.setVariables(taskId, variables); //启动流程实例的时候也可以设置流程变量
//runtimeService.startProcessInstanceById(arg0, arg1)
//完成任务提交时,也可以设置流程变量
//taskService.complete(arg0, arg1); /**
* 设置流程变量,还可以用javaBean类型
* 但要求JavaBean可序列化,且当JavaBean放入流程变量中,要求JavaBean的属性不能再发生变化
* 如果发生变化,再获取的时候,抛出异常;
* 也可指定实体的序列化版本id
*
* 序列化的值存储在资源文件表
*/ /**
* taskService.setVariableLocal(arg0, arg1, arg2);
*
* setVariableLocal 和 setVariable的区别:
* setVariable设置流程变量的时候,流程变量名称相同的时候,后一次的值替换前一次的值,
* 而且TASK_ID不存放任务ID的值
* setVariableLocal:设置流程变量的时候,针对当前活动的节点设置流程变量,如果一个流程中存在2个活动节点,
* 对每个活动节点都设置流程变量,及时流程变量的名称相同,后一次的版本的值也不会替换前一次版本的值,他会使用不同的
* 任务ID作为标识,存放2个流程变量值,而且恶意看到TASK_ID额度字段会存放任务ID的值;
*
* 还有使用setVariableLocal说明流程变量绑定了当前的任务,当流程继续执行时,下个任务获取不到这个流程变量(
* 以为正在执行的流程变量中没有这个数据),所有查询正在执行的任务时不能查询到我们需要的数据,此时需要查询历史的流程变量
*/ //获取流程变量用get
runtimeService.getVariable("执行对象ID", "变量名称");
runtimeService.getVariables("执行对象ID");//返回map参数集合
//runtimeService.getVariables("执行对象ID", list)//指定参数集合 return "";
} /**
* 完成我的任务
* @return
*/
@RequestMapping("completeTask")
public String completeTask(){ String taskId = "17502"; processEngine.getTaskService().complete(taskId); return "完成任务" + taskId;
} /**
* 查询历史流程变量
* @return
*/
@GetMapping("findHistoryVariables")
public String findHistoryVariables(){ List<HistoricVariableInstance> list = processEngine.getHistoryService()
.createHistoricVariableInstanceQuery()
.variableName("请假原因")
.list(); System.out.println(list.size()); return "success"; } }
4、 历史查询 HistoryService
由于数据库中保存着历史信息以及正在运行的流程实例信息,再实际项目中对已完成任务的查看频率远不及对代办和可接任务的查看,所以再activiti采用分开管理,把正在运行的交给RuntimeService、TaskService管理,而历史数据交给HistoryService来管理。这样做的好处在于,加快流程执行的速度,因为正在执行的流程的表中数据不会很大。
Activiti工作流引擎学习(一)的更多相关文章
- activiti工作流引擎学习(三)
5.接收任务活动(receiveTask,即等待活动)不是一个任务节点 接收任务是一个简单任务,他会等待回应消息的到达,当前,官方只实现了这个任务的java语义,当流程达到接受任务,流程状态会保存到数 ...
- activiti工作流引擎学习(二)
1.连线 如果bpmn文件和java文件放在同一目录下,需要配置buildPath: 使用流程变量,设置连线需要的流程变量的名称,并设置流程变量的值,流程会按照指定的连线完成任务. 1.1一个活动中可 ...
- Activiti工作流引擎开发系列
Activiti工作流引擎开发系列-01 作者:Jesai 没有伞的孩子,只能光脚奔跑! 前言: 初次接触工作流这个概念是自从2014年11月份开始,当时是由于我的毕业设计需要,还记得当时我毕业设计的 ...
- Activiti工作流引擎参考资料
Activiti工作流引擎使用 工作流-Activiti核心API介绍 传智播客Activiti工作流视频教程(企业开发实例讲解) 工作流引擎Activiti演示项目 http://www.kafei ...
- Activiti工作流引擎简介
Activiti工作流引擎简介 一.概述 Activiti是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理,工作流,服务协作等领域的一个开源,灵活 ...
- Activiti工作流引擎数据库表结构
Activiti工作流引擎数据库表结构 一.数据库表的命名 Acitiviti数据库中表的命名都是以ACT_开头的.第二部分是一个两个字符用例表的标识.此用例大体与服务API是匹配的. ACT_RE_ ...
- Activiti工作流框架学习(一)之通用数据表详细介绍
文/朱季谦 Activiti工作流引擎自带了一套数据库表,这里面有一个需要注意的地方: 低于5.6.4的MySQL版本不支持时间戳或毫秒级的日期.更糟糕的是,某些版本在尝试创建此类列时将引发异常,而其 ...
- Activiti工作流框架学习笔记(二)之springboot2.0整合工作流Activiti6.0
以前在工作当中做过不少与工作流Activiti有关的工作,当时都是spring集成activiti5.22的项目,现在回过头去看,其实版本已经稍微老了,因此,基于先前的工作经验,决定用较新版本的技术来 ...
- activiti工作流引擎
参考文章 Activiti-5.18.0与springMvc项目集成和activiti-explorer单独部署Web项目并与业务数据库关联方法(AutoEE_V2实现方式) https://blog ...
随机推荐
- jQuery动态加载动画spin.js
在线演示 本地下载
- day39-Spring 02-AOP的概述
横向抽取的机制其实就是代理机制.对UserDao生成一个代理类:UserDaoProxy.被代理对象和代理对象它俩实现相同的接口它俩肯定是平级的,这就是横向抽取的机制.如果这时候调用UserDao的 ...
- 使用Velero Restic快速完成云原生应用迁移至ACK集群
本文记录使用Velero Restic快速完成云原生应用迁移至ACK集群的实践过程. 0. 实践步骤概览 (1)创建GKE集群(或自建Kubernetes集群)(2)在GKE集群上部署示例应用Jenk ...
- Request.Cookies和Response.Cookies
Request.Cookies创建的Cookie只能用于后台不能用于HTML的前台Response.Cookies操作过的Cookie,所有方法获取到的都是被更新过的值,也就是说Response.Co ...
- 设置onselectstart在ie浏览器下对于input及textarea标签页会生效
设置onselectstart在ie浏览器下对于input及textarea标签页会生效, 可以使用js来控制对于某种标签不生效,代码如下: document.onselectstart = disa ...
- 2019.9.10附加题while练习
题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40万之 ...
- python 源文件编码
- 【UTR #1】ydc的大树
[UTR #1]ydc的大树 全网唯一一篇题解我看不懂 所以说一下我的O(nlogn)做法: 以1号点为根节点 一个黑点如果有多个相邻的节点出去都能找到最远的黑点,那么这个黑点就是无敌的 所以考虑每个 ...
- 关于取List中的指定几条数据以及注意事项
list1 = list2.subList(start, end); start,end分别是第几个到第几个. 注意的是此方法和substring一样,包含前不包含结尾,取下标索引 另一个注意的地方是 ...
- python 列表长度