方式一
通过idea搜索actiBPM来安装插件
方式二
通过去官网查找actiBPM插件将插件下载下来通过如图所示的方式安装插件
1)创建maven工程,在pom.xml文件中添加activiti所需的各种jar包
activiti-engine-7.0.0.beta1.jar
activiti 依赖的 jar 包: mybatis、 alf4j、 log4j 等
activiti 依赖的 spring 包
mysql数据库驱动(数据库驱动可以更具自己所需而变动,详细参照activiti支持的数据库)
第三方数据连接池 dbcp
单元测试 Junit-4.12.jar(为了测试使用activiti)
<properties>
<slf4j.version>1.6.6slf4j.version>
<log4j.version>1.2.12log4j.version>
<activiti.version>7.0.0.Beta1activiti.version>
properties>
<dependencies>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-engineartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-springartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-modelartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-converterartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-json-converterartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-layoutartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>org.activiti.cloudgroupId>
<artifactId>activiti-cloud-services-apiartifactId>
<version>${activiti.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.40version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.5version>
dependency>
<dependency>
<groupId>commons-dbcpgroupId>
<artifactId>commons-dbcpartifactId>
<version>1.4version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
dependencies>
2)在resources文件夹下创建日志文件以及activiti所需配置文件
activiti.cfg.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///activititest?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"/>
<property name="jdbcUsername" value="root"/>
<property name="jdbcPassword" value="123456"/>
<property name="databaseSchemaUpdate" value="true"/>
bean>
beans>
日志文件log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=f:\act\activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
执行以下代码activiti回自动帮助你创建用于控制工作流的表。共计25张.
/**
* 生成 activiti的数据库表
*/
@Test
public void testCreateDbTable() {
//使用classpath下的activiti.cfg.xml中的配置创建processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
}
表分类 | 表名 | 解释 |
---|---|---|
一般数据 | ||
[ACT_GE_BYTEARRAY] | 通用的流程定义和流程资源 | |
[ACT_GE_PROPERTY] | 系统相关属性 | |
流程历史记录 | ||
[ACT_HI_ACTINST] | 历史的流程实例 | |
[ACT_HI_ATTACHMENT] | 历史的流程附件 | |
[ACT_HI_COMMENT] | 历史的说明性信息 | |
[ACT_HI_DETAIL] | 历史的流程运行中的细节信息 | |
[ACT_HI_IDENTITYLINK] | 历史的流程运行过程中用户关系 | |
[ACT_HI_PROCINST] | 历史的流程实例 | |
[ACT_HI_TASKINST] | 历史的任务实例 | |
[ACT_HI_VARINST] | 历史的流程运行中的变量信息 | |
流程定义表 | ||
[ACT_RE_DEPLOYMENT] | 部署单元信息 | |
[ACT_RE_MODEL] | 模型信息 | |
[ACT_RE_PROCDEF] | 已部署的流程定义 | |
运行实例表 | ||
[ACT_RU_EVENT_SUBSCR] | 运行时事件 | |
[ACT_RU_EXECUTION] | 运行时流程执行实例 | |
[ACT_RU_IDENTITYLINK] | 运行时用户关系信息,存储任务节点与参与者的相关信息 | |
[ACT_RU_JOB] | 运行时作业 | |
[ACT_RU_TASK] | 运行时任务 | |
[ACT_RU_VARIABLE] | 运行时变量表 |
1)创建bpmn文件,并通过插件绘制bpmn流程图(可转为xml文件以及png文件)。
点开bpmn文件如下图
在这里插入图片描述](https://img-blog.csdnimg.cn/20210605161837578.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hZ2ljcHJvYmxlbQ==,size_16,color_FFFFFF,t_70)
简单的绘制工作流,如下图所示
2)将文件的扩展名改为.xml则如下所示
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/testm1622878134337" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1622878134337" name="" targetNamespace="http://www.activiti.org/testm1622878134337" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="myFlow01" isClosed="false" isExecutable="true" processType="None">
<startEvent id="start1" name="StartEvent"/>
<userTask activiti:assignee="操作员01" activiti:candidateUsers="候选人01" activiti:exclusive="true" id="flow01" name="发送请假申请"/>
<userTask activiti:assignee="操作员02" activiti:candidateUsers="候选人02" activiti:exclusive="true" id="flow02" name="主管审批"/>
<endEvent id="end1" name="EndEvent"/>
<sequenceFlow id="_6" sourceRef="start1" targetRef="flow01"/>
<sequenceFlow id="_7" sourceRef="flow01" targetRef="flow02"/>
<sequenceFlow id="_8" sourceRef="flow02" targetRef="end1"/>
process>
<bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
<bpmndi:BPMNPlane bpmnElement="myFlow01">
<bpmndi:BPMNShape bpmnElement="start1" id="Shape-start1">
<dc:Bounds height="32.0" width="32.0" x="310.0" y="85.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="flow01" id="Shape-flow01">
<dc:Bounds height="55.0" width="85.0" x="285.0" y="165.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="flow02" id="Shape-flow02">
<dc:Bounds height="55.0" width="85.0" x="285.0" y="260.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end1" id="Shape-end1">
<dc:Bounds height="32.0" width="32.0" x="310.0" y="360.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_2" targetElement="_3">
<di:waypoint x="326.0" y="117.0"/>
<di:waypoint x="326.0" y="165.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_3" targetElement="_4">
<di:waypoint x="327.5" y="220.0"/>
<di:waypoint x="327.5" y="260.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_4" targetElement="_5">
<di:waypoint x="326.0" y="315.0"/>
<di:waypoint x="326.0" y="360.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
bpmndi:BPMNLabel>
bpmndi:BPMNEdge>
bpmndi:BPMNPlane>
bpmndi:BPMNDiagram>
definitions>
3)转为图片则需先转为xml文件,通过如图以下操作即可转为图片,如果没有Diagrams可参考idea actiBPM插件生成png文件 (解决没有Diagrams或Designer选项问题)
1)部署流程定义
/**
* 部署流程定义
*/
@Test
public void testDeployment(){
// 1、创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、得到RepositoryService实例
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3、使用RepositoryService进行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("bpmn/myFlow01.bpmn") // 添加bpmn资源
.addClasspathResource("bpmn/myFlow01.xml") // 添加xml资源
.addClasspathResource("bpmn/myFlow01.png") // 添加png资源
.name("请假申请流程01")
.deploy();
// 4、输出部署信息
System.out.println("流程部署id:" + deployment.getId());
System.out.println("流程部署名称:" + deployment.getName());
}
执行结果
数据库表变动
流程定义部署后操作activiti的3张表如下:
act_re_deployment 流程定义部署表,每部署一次增加一条记录
act_re_procdef 流程定义表,部署每个新的流程定义都会在这张表中增加一条记录
act_ge_bytearray 流程资源表
2)启动流程实例
/**
* 启动流程实例
*/
@Test
public void testStartProcess(){
// 1、创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3、根据流程定义Id启动流程
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("myFlow01");
// 输出内容
System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
System.out.println("流程实例id:" + processInstance.getId());
System.out.println("当前活动Id:" + processInstance.getActivityId());
}
运行结果
数据库表变动
act_hi_actinst 流程实例执行历史
act_hi_identitylink 流程的参与用户历史信息
/**
* 完成个人任务
*/
@Test
public void completeTask(){
String ass = "操作员01";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
//查询该用户是否有该任务
Task task = taskService.createTaskQuery().taskAssignee(ass).singleResult();
//将查询个人任务完成act_ru_task,完成后会将历史记录存在hi表中,当前任务会变成下一个阶段的任务
if (task == null){
System.out.println(ass+"没有任务");
}else
System.out.println(ass+"完成任务"+task.getName()+"--"+task.getId());
taskService.complete(task.getId());
}
运行结果
数据库变动基本与启动流程实例一致以act_hi的表新增当前流程记录,以及修改上一步流程的结束时间,而act_ru的都变为当前这个流程阶段的信息如图所示。
act_ru_task 任务信息
act_hi_actinst 流程实例执行历史
4)删除流程
/**
* 删除流程
* 1、删除流程定义,如果该流程定义已有流程实例启动则删除时出错(未完成该流程)
* 2、设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除(未完成的流程实例被删除)
* act_hi的表是不会被删除的
* 主要是删除act_ru以及部署时操作的那几张表的相关信息
*/
@Test
public void deleteDeployment() {
// 流程部署id
String deploymentId = "12501";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 通过流程引擎获取repositoryService
RepositoryService repositoryService = processEngine
.getRepositoryService();
//
repositoryService.deleteDeployment(deploymentId);
//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除
//repositoryService.deleteDeployment(deploymentId, true);
}
运行结果
结果1(使用repositoryService.deleteDeployment(deploymentId);):
结果2(使用repositoryService.deleteDeployment(deploymentId, true);):
数据库表变动:
act_re_deployment
act_ge_bytearray
使用repositoryService.deleteDeployment(deploymentId);,在有流程实例未完成的状态下act_ru等表中相关数据被删,act_hi的流程完成记录还在
使用repositoryService.deleteDeployment(deploymentId, true);,则关联的信息全部被删,包括act_hi
act_ru_task
act_ru_identitylink
等等act_ru以及act_hi表
5)流程历史信息的查询
/**
* 查看历史信息
*/
@Test
public void findHistoryInfo(){
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
// 获取 actinst表的查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
// 查询 actinst表,条件:根据 InstanceId 查询
// instanceQuery.processInstanceId("2501");
// 查询 actinst表,条件:根据 DefinitionId 查询
instanceQuery.processDefinitionId("12501");
// 增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
// 查询所有内容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
// 输出
for (HistoricActivityInstance hi : activityInstanceList) {
System.out.println(hi.getActivityId());
System.out.println(hi.getActivityName());
System.out.println(hi.getProcessDefinitionId());
System.out.println(hi.getProcessInstanceId());
System.out.println("<==========================>");
}
}
6)流程资源的下载
需要引入commons-io的jar包
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.6version>
dependency>
/**
* 流程资源的下载
* @throws IOException
*/
@Test
public void queryBpmnFile() throws IOException {
// 1、得到引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取repositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3、得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("myFlow01")
.singleResult();
// 4、通过流程定义信息,得到部署ID
String deploymentId = processDefinition.getDeploymentId();
// 5、通过repositoryService的方法,实现读取图片信息和bpmn信息
// png图片的流
InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
// bpmn文件的流
InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
// 6、构造OutputStream流
File file_png = new File("d:/flow01.png");
File file_bpmn = new File("d:/flow01.bpmn");
FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
FileOutputStream pngOut = new FileOutputStream(file_png);
// 7、输入流,输出流的转换
IOUtils.copy(pngInput,pngOut);
IOUtils.copy(bpmnInput,bpmnOut);
// 8、关闭流
pngOut.close();
bpmnOut.close();
pngInput.close();
bpmnInput.close();
}