Activiti5工作流笔记一
介绍工作流
网上工作流的定义一大堆,这里就不去复制了,通俗的理解,工作流就是类似OA系统中请假审批、报销审批等一系列流程,下级提交的申请只有直系领导才能审批,其他人是没有权限的,而只有直系领导审批通过后,直系领导的直系领导才可以看到申请,并进行审批,以此类推。。。
而Activiti工作流就可以实现类似的功能,本笔记将以最简单的方式让你明白怎么使用Activiti工作流,直接上代码
准备环境
1) JDK1.6或者更高版本
2) 支持的数据库有:h2, mysql, oracle, postgres, mssql, db2等。
3) 支持activiti5运行的jar包
4) 开发环境为Eclipse3.7或者以上版本,myeclipse为8.6版本
安装流程设计器(eclipse插件)
方案一:
在有网络的情况下,安装流程设计器步骤如下:
1) 打开 Help -> Install New Software. 在如下面板中:
2) 在如下Install界面板中,点击Add按钮:
3) 然后填入下列字段
Name: Activiti BPMN 2.0 designer
Location: http://activiti.org/designer/update/
4) 回到Install界面,在面板正中列表中把所有展示出来的项目都勾上:
5) 点击复选框
在Detail部分记得选中 "Contact all updates sites.." , 因为它会检查所有当前安装所需要的插件并可以被Eclipse下载.
6) 安装完以后,点击新建工程new->Other…打开面板,如果看到下图内容:
说明安装成功了。
方案二
在没有网络的情况下,安装流程设计器步骤如下:
首先下载离线插件包:
https://files.cnblogs.com/files/lm970585581/activiti.zip
将压缩包解压后
这两个文件夹复制到Eclipse根目录下 ,重启即可
注意:
打开菜单Windows->Preferences->Activiti->Save下流程流程图片的生成方式:
虽然流程引擎在单独部署bpmn文件时会自动生成图片,但在实际开发过程中,自动生成的图片会导致和BPMN中的坐标有出入,在实际项目中展示流程当前位置图会有问题。
所在完成以上配置后,会由我们自己来管理流程图片。在发布流程时把流程规则文件和流程图片一起上传就行了。
准备Activiti5开发环境
在activiti-5.13->wars目录下是一些示例项目,解压activiti-rest项目,导入activiti-rest目录中WEB-INF\lib下所有包。添加到classpath中。
另外需要根据我们正在使用的数据库添加相应的数据库jar包
初始化数据库
可以在activiti-rest\WEB-INF\classes下找到配置文件:如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://192.168.220.130:3306/activiti?useUnicode=true&characterEncoding=utf8"></property>
<property name="jdbcUsername" value="root"></property>
<property name="jdbcPassword" value="root"></property>
<!--
创建表的策略
-->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>
调用以下java代码,即可把需要的表创建出来
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.junit.Test; public class CreateTable {
@Test
public void testCreateTable(){
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")
.buildProcessEngine();
}
}
HelloWorld程序
先画请假流程图
注意:
properties=>General中的ID和NAME可以设置每个步骤的名称:
每个审批过程的properties=>Main config=>Assignee:设置能够审批的对象,这里部门经理审批设置为:张三,总经理审批设置为:李四
保存后,在根目录下生成:
JAVA程序如下:
import java.util.List; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.task.Task;
import org.junit.Test; /**
* 1、部署流程图
* 2、启动流程实例
* 3、发起申请
* 4、审批
* @author zd
*
*/
public class HelloWorld {
/**
* 部署流程图
*/
@Test
public void testDeploy(){
//产生流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库流程的实例
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("qingjia.bpmn")
.addClasspathResource("qingjia.png")
.deploy();
/**
* 这里使用RepositoryService部署流程定义
addClasspathResource表示从类路径下加载资源文件,一次只能加载一个文件
*/
} /**
* 启动流程实例 pi=process instance
*/
@Test
public void testStartPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceById("qingjia:1:4");//ID在act_re_procdef这个表中可以看到
//这里使用RuntimeService启动流程实例
} /**
* 完成任务
*/
@Test
public void testFinishTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("104");//act_ru_task表中获取
} /**
* 根据张三查询任务
*/
@Test
public void testQueryTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//查询任务列表
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.list();
for (Task task : tasks) {
System.out.println(task.getName());
}
}
}
流程定义
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipInputStream; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;
import org.springframework.transaction.annotation.Transactional; /**
* pd=process definition
* @author zd
* 1、把流程图部署到activiti的引擎中 重点
* classpath
* inputstream
* zipinputstream
* 2、对流程图进行删除 重点
* 3、获取到流程图和bpmn文件 重点
* 4、查询 了解
* 查询部署
* 查询流程定义
*/
public class PDTest {
/**
* 涉及到的表
* act_ge_bytearray
* 1、说明
* 该表存储了bpmn文件和png图片
* 从字段可以看出,根据deploymentID可以查询bpmn文件和png图片
* 2、字段
* name_:存储该文件的路径名称
* deploymentid_id_:部署表的ID
* byte_:存放值(bpmn和png)
* act_re_deployment
* 1、说明
* 该表存储了部署的动作
* 2、字段
* ID_:部署ID 主键
* act_re_procdef
* 1、说明
* 流程定义表
* 2、字段
* id: 是由${name}:${version}:随机数 确定唯一的流程
* name_: 流程定义名称
* key_: 流程定义名称
* version_: 某一个流程定义的版本
* deployment_id_:部署表的ID
*
* 说明:
* 1、根据deploymentID-->查询图片和bpmn文件
* 2、根据deploymentID-->查询流程定义
* 3、只要流程名称不变,部署一次,版本号加1,id就发生变化,生成了一个新的deploymentID
* 4、所以deploymentID和pdid是一一对应的关系
*/
@Test
public void testDeployFromClasspath(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("qingjia.bpmn")
.addClasspathResource("qingjia.png")
.deploy();
} /**
* 通过inputStream的方式部署
*/
@Test
public void testDeployFromInputStream(){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("qingjia.bpmn");
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addInputStream("qingjia.bpmn", inputStream)
.deploy();
} /**
* 通过zip的方式部署
*/
@Test
public void testDeployFromZip(){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("qingjia.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
} /**
* 把查询出来的图片放到E盘的根目录下
*/
@Test
public void testShowImage() throws Exception{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
InputStream inputStream = processEngine.getRepositoryService()
/**
* 参数为pdid
*/
.getProcessDiagram("qingjia:1:4");
/**
* 得到一个图片
*/
// OutputStream outputStream = new FileOutputStream("e:/processimg.png");
// for(int b=-1;(b=inputStream.read())!=-1;){
// outputStream.write(b);
// }
// inputStream.close();
// outputStream.close();
/***************************************************************************************/
/**
* 第一个参数为deploymentId
* 第二个参数为resourceName
*/
/********************************************************************************/
/**
* 得到的是一个图片
*/
// InputStream inputStream2 = processEngine.getRepositoryService()
// .getResourceAsStream("101", "qingjia.png");
//
// OutputStream outputStream2 = new FileOutputStream("e:/processimg2.png");
// for(int b=-1;(b=inputStream2.read())!=-1;){
// outputStream2.write(b);
// }
// inputStream2.close();
// outputStream2.close();
/**********************************************************************************/
/**
* 得到的是bpmn文件
*/
InputStream inputStream3 = processEngine.getRepositoryService()
.getProcessModel("qingjia:1:4");
OutputStream outputStream3 = new FileOutputStream("e:/processimg3.bpmn");
for(int b=-1;(b=inputStream3.read())!=-1;){
outputStream3.write(b);
}
inputStream3.close();
outputStream3.close();
/*************************************************************************************/ } /**
* 查询流程部署
*/
@Test
public void testQueryDeploy(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Deployment> deployments = processEngine.getRepositoryService()
.createDeploymentQuery()
.list();
for (Deployment deployment : deployments) {
System.out.println(deployment.getId());
}
} /**
* 根据部署ID查询部署 一个结果
*/
@Test
public void testQueryDeployById(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService()
.createDeploymentQuery()
.deploymentId("1")
.singleResult(); System.out.println(deployment.getId()); } /**
* 查询所有的流程定义
*/
@Test
public void testQueryPD(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> processDefinitions = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.list();
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println(processDefinition.getKey());
System.out.println(processDefinition.getId());
System.out.println(processDefinition.getVersion());
}
} /**
* 按照版本的从高到低进行排序
*/
@Test
public void testQueryPDByVersion(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> processDefinitions = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.orderByProcessDefinitionVersion()
.desc()
.list();
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println(processDefinition.getKey());
System.out.println(processDefinition.getId());
System.out.println(processDefinition.getVersion());
}
} /**
* 根据pdid查询流程定义
* 根据 pdkey查询流程定义
*/
//略。。 /**
* 删除
*/
@Test
public void testDelete(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
//.deleteDeployment("");//该方法只能删除流程定义,一般不会使用
.deleteDeployment("1", true);//该方法不仅能够删除流程定义,而且能够删除正在运行的流程实例
}
}
流程实例、任务的执行
import java.util.List; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.bpmn.parser.handler.ProcessParseHandler;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test; /**
* pi=process instance
* @author zd
* 1、启动流程实例
* 2、完成任务
* 3、任务的查询
* 1、根据任务的执行人查询任务
* 2、可以根据任务查询任务的执行人
* 3、查看历史任务
* 4、怎么样查看流程实例是否结束
*/
public class PITest {
/**
* 启动流程实例
* 涉及到的表
* act_hi_actinst hi:history actinst:action instance
* 1、概念
* 所有的正在执行的或者已经完成的节点
* 2、字段
* act_type_:为节点的类型
* end_time_: 如果有值,说明该节点已经结束了
* act_hi_procinst procinst:process instance
* 1、概念
* 所有的正在执行的或者已经完成的流程实例
* 2、字段
* end_time_:如果该字段有值,说明这个流程实例已经结束了
* end_act_id_:说明该流程实例是在哪个节点结束的
* act_hi_taskinst taskinst:task instance
* 1、概念
* 所有的正在执行的或者已经完成的任务节点
* 2、字段
* end_time_:如果该字段有值,说明任务已经完成了
* delete_reason:如果该值为completed,说明该任务处于完成的状态
* act_ru_execution ru:runtime
* 1、概念
* 代表正在执行的流程实例
* 2、字段
* id_:主键 executionid
* proc_inst_id_: process instanceid
* proc_def_id_:pdid
* act_id_:当前的流程实例正在执行的节点的ID的值
* act_ru_task
* 1、概念
* 代表正在执行的任务
* 2、字段
* id_:主键 任务ID
* execution_id_:piid,executionid
* name_:任务名称
* 3、说明
* 该表是一个临时表,该表中的任务完成以后,这一行会被删除掉
*
*/
@Test
public void testStartPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceById("qingjia:1:304");
System.out.println(pi.getId());
} /**
* 查询所有的正在执行的流程实例
*/
@Test
public void testQueryPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessInstance> processInstances = processEngine.getRuntimeService()
.createProcessInstanceQuery()
.list();
for (ProcessInstance processInstance : processInstances) {
System.out.println(processInstance.getActivityId());
System.out.println(processInstance.getId());
}
} /**
* 查询当前正在执行的节点
*/
@Test
public void testQueryActivity(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<String> strings = processEngine.getRuntimeService()
.getActiveActivityIds("401");
for (String string : strings) {
System.out.println(string);
}
} /**
*获取当前的流程实例正在运行的节点的坐标
*/
@Test
public void getPix(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* processDefinitionEntity代表流程图对象的实体
*
* 根据pdid获取到流程定义实体
*/
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)processEngine.getRepositoryService()
.getProcessDefinition("qingjia:1:304");
List<String> strings = processEngine.getRuntimeService()
.getActiveActivityIds("401"); //piid
for (String string : strings) {
/**
* ActivityImpl代表流程图上的每一个节点
*/
ActivityImpl activityImpl = processDefinitionEntity.findActivity(string);
/**
* 获取到正在执行的流程节点的坐标
*/
System.out.println(activityImpl.getHeight());
System.out.println(activityImpl.getWidth());
System.out.println(activityImpl.getX());
System.out.println(activityImpl.getY());
}
} /**
* 查询所有的任务
*/
@Test
public void testQueryAllTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.list();
for (Task task : tasks) {
System.out.println(task.getId());
System.out.println(task.getName());
}
} /**
* 完成任务
* 需要一个参数:taskId
*/
@Test
public void testFinishTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("602");
} /**
* 根据任务的执行人查看任务
*/
@Test
public void testQueryTaskByAssignee(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.list();
for (Task task : tasks) {
System.out.println(task.getId());
System.out.println(task.getName());
}
} /**
* 根据任务的执行人查看任务,并且按照时间的倒叙排序
*/
@Test
public void testQueryTaskByAssigneeByTime_DESC(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.orderByTaskCreateTime()
.desc()
.list();
for (Task task : tasks) {
System.out.println(task.getId());
System.out.println(task.getName());
}
} /**
* 根据piid判断流程实例是否结束
*/
@Test
public void testQueryPIByPIID(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessInstance pi = processEngine.getRuntimeService()
.createProcessInstanceQuery()
.processInstanceId("401")
.singleResult();
if(pi==null){
System.out.println("该流程实例已经结束了");
}else{
System.out.println("该流程实例正在执行中");
}
} /**
* 查询已经完成的任务
*/
@Test
public void testQueryHistoryTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<HistoricTaskInstance> historicTaskInstances = processEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
.finished()
.list();
for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
System.out.println(historicTaskInstance.getAssignee());
System.out.println(historicTaskInstance.getName());
System.out.println(historicTaskInstance.getId());
}
} /**
* 查询已经完成的activityimpl
*/
@Test
public void testQueryHistoryActivityImpl(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<HistoricActivityInstance> historicActivityInstances = processEngine.getHistoryService()
.createHistoricActivityInstanceQuery()
.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
System.out.println(historicActivityInstance.getActivityName());
}
}
}
Activiti5工作流笔记一的更多相关文章
- Activiti5工作流笔记四
排他网关(ExclusiveGateWay) 流程图 部署流程定义+启动流程实例 查询我的个人任务 完成我的个人任务 并行网关(parallelGateWay) 流程图 部署流程定义+启动流程实例 查 ...
- Activiti5工作流笔记三
组任务 直接指定办理人 流程图如下: import java.util.HashMap; import java.util.List; import java.util.Map; import org ...
- Activiti5工作流笔记二
流程变量 import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.activiti ...
- Java_Activiti5_菜鸟也来学Activiti5工作流_之初识常用服务类和数据表(二)
/** * 代码清单中使用 ProcessEngines类加载默认的流程配置文件(activiti.cfg.xml),再获取各个服务组件的实例. * RepositoryService主要用于管理流程 ...
- activiti工作流笔记
什么是activiti? Activiti是一个身经百战的业务流程管理引擎, 并且还是一个流程平台 为什么要用工作流引擎? 简单来说,就是为了统一管理流程业务. 想想看,如果要设计一个流程的程序,通常 ...
- Activiti工作流笔记(4)
Activiti工作流启动流程 /** * 启动流程 * */ public class ActivitiTest2 { RepositoryService repositoryService; Ru ...
- Activiti工作流笔记(3)
Activiti工作流的流程部署和删除流程部署 流程部署代码: /** * 部署流程 */ public class ActivitiTest { RepositoryService reposito ...
- Activiti工作流笔记(2)
1.Activiti工作数据表 Activiti用来存放流程数据的表共使用23张表,表名都是以"ACT_"开头,底层操作默认使用mybatis操作 工作流Activiti的表是用来 ...
- Activiti工作流笔记(1)
Activiti下载地址: eclipse的activiti插件下载地址:http://www.activiti.org/designer/archived/activiti-designer-5.1 ...
随机推荐
- 数据库 MySQL part3
外键约束 如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表. 外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操 ...
- 北京Uber优步司机奖励政策(12月31日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- QImage对一般图像的处理
QImage对一般图像的处理 Qt中QImage类封装了对于一般图像像素级的操作,图像显示则使用QPixmap. 本文说说对一般图像(常见格式,图像不大)的处理,比如将彩色图像处理为灰度图像.首先要获 ...
- Win10 远程服务器版
朋友的电脑刚装了1803版的Win10,然后他用KMS_VL_ALL6.9激活了一下,竟然变成了一个奇怪的版本:“远程服务器版”!第一次见这玩意,还真稀罕.帮他研究了一下,发现KMS_VL_ALL在激 ...
- nodejs学习笔记(2)
1.express超时设置 如果http请求在一段时间内没有返回值,express会重新向后台发送请求.在后台方法执行时间较长的情况下,重复的请求会重复执行,造成前台接收到空的response,出现E ...
- 使用unittest里面的discover()方法组织测试用例
import osimport unittest directory = os.getcwd()# 测试用例的目录organize = unittest.defaultTestLoader.disco ...
- linux部署maven
1.下载安装包 https://maven.apache.org/download.cgi 2.解压,并配置环境变量 vim /etc/profile export MAVEN_HOME=maven目 ...
- 第一阶段·Linux运维基础 第3章·文件属性、正则表达式、文件权限
01-文件属性内容介绍 02- inodeyublock讲解 03-访问oldboyfile的寻宝过程 04-inode与block小结 05-磁盘空间不足案例详解 06-Linux文件类型及拓展名 ...
- mybatis interceptor 处理查询参数及查询结果
拦截器:拦截update,query方法,处理查询参数及返回结果. /** * Created by windwant on 2017/1/12. */ @Intercepts({ @Signatur ...
- 从零开始的Python学习Episode 4——列表
一.列表 列表与数组相似,定义一个列表 a=[1,2,3,4,5] 1.基本操作 a=[1,2,3,4] #切片 范围取值时,包括第一项但不包括最后一项,顾头不顾尾 print(a[0:]) #从头到 ...