Activiti7基础
1.工作流介绍
相关概念
工作流:工作从开始到结束的一个流程,可以通过计算机实现流程自动化管理,比如钉钉请假审批
工作流引擎:能够实现流程自动化控制的工具(比如正在学的Activiti)
工作流系统:具有工作流功能的系统
工作流系统
适用于各个行业的流程处理
1.实现方式
- 程序员编码(不灵活,流程变更就很难受), 比如请假 各级领导审批的状态使用数据库表某个字段记录即可(0同意 1不同意)
- 使用第三方工作流框架 Activiti,哈哈哈,,,,,
2.工作流实现原理分析
如何可以做到我们在业务流程发生变更后,我们的业务系统代码可以不发生改变?
此时我们就来分 析一下原理。
具体分析过程如下图所示:
这张表就相当于activiti7中的 act_ru_task 表
2.Activiti7基础
Activiti是一个项目的名称,Alfresco软件在2010年5月17日宣布Activiti业务流程管理(BPM)开源项目的正式启动,其首席架构师由业务流程管理BPM的专家 Tom Baeyens担任
1.相关概念
- BPM(Business Process Management),即业务流程管理。是一种以规范化的构造端到端的卓越 业务流程为中心,以持续的提高组织业务绩效为目的系统化方法
- BPM软件:画业务流程图的软件(专业软件)
- BPMN:(Business Process Model And Notation)- 业务流程模型和符号,BPM流程图的一种规范
2.Activiti使用步骤
步骤:
SaaS-IHRM
- 1.整合Actviti
- 2.实现业务流程建模,使用BPMN实现业务流程图
- 3.部署业务流程到Activiti
- 4.启动流程实例
- 5.查询待办任务
- 6.处理待办任务
- 7.结束流程
3.IDEA画BPMN图
IDEA安装流程设计器Activitidesigner(actiBPM插件)
IDEA2021搜索不到。。。
1.去官网下载插件
https://plugins.jetbrains.com/
发现该插件没有对2021版本的idea进行维护
将该插件下载到本地,然后IDEA去本地安装插件
还是不行,要不降低版本到idea2019以下,要不找其他的画bpmn图的工具。。。。
4.画图软件
搞个第三方war包部署到tomcat中启动使用
5.准备工作(生成25张表)
支持的数据库:h2,mysql,oracle,postgres,db2,mssql
生成我们需要的25张表
步骤:
1.导入相关依赖
2.配置数据库,log4j.以及activiti要用的对象
3.测试 生成25张表
1.导入相关依赖
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.activiti.cloud</groupId>
<artifactId>activiti-cloud-services-api</artifactId>
<version>7.0.0.Beta1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
2.配置数据库,log4j.以及activiti要用的对象 (activiti.cfg.xml)
<?xml version="1.0" encoding="UTF-8"?>
<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="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://47.107.93.172:3306/activiti7?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"></property>
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
3.测试 生成25张表
//生成25张表
@Test
public void test1(){
//加载配置文件
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//获取processEngine对象 生成25张表
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println(processEngine);
}
3.表结构设计说明
数据库表的命名规则
Activiti 的表都以 ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的 API 对 应。
- ACT_RE_: 'RE'表示 repository。 这个前缀的表包含了流程定义和流程静态资源 (图片, 规则,等等)。
- ACT_RU_: 'RU'表示 runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务, 等运行中的数据。 Activiti 只在流程实例执行过程中保存这些数据, 在流程结束时就会删 除这些记录。 这样运行时表可以一直很小速度很快。
- ACT_HI_: 'HI'表示 history。 这些表包含历史数据,比如历史流程实例, 变量,任务等 等。
- ACT_GE_: GE 表示 general。通用数据, 用于不同场景下。
4.Activiti 服务架构
我们就通过各个service来操作25张表(无需自己实现),进而简化开发
5.activiti 入门体验
1.定义流程
(画bpmn图),实际上就是一个xml文件
holiday.bpmn
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" 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="m1540200341676" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="holiday" isClosed="false" isExecutable="true" name="请假流程" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:assignee="zhangsan" activiti:exclusive="true" id="_3" name="填写请假申请单"/>
<userTask activiti:assignee="lisi" activiti:exclusive="true" id="_4" name="部门经理审批"/>
<userTask activiti:assignee="wangwu" activiti:exclusive="true" id="_5" name="总经理审批"/>
<endEvent id="_6" name="EndEvent"/>
<sequenceFlow id="_7" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="_8" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="_9" sourceRef="_4" targetRef="_5"/>
<sequenceFlow id="_10" sourceRef="_5" targetRef="_6"/>
</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="holiday">
<bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
<omgdc:Bounds height="32.0" width="32.0" x="280.0" y="45.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
<omgdc:Bounds height="55.0" width="85.0" x="255.0" y="140.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
<omgdc:Bounds height="55.0" width="85.0" x="255.0" y="245.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
<omgdc:Bounds height="55.0" width="85.0" x="255.0" y="350.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
<omgdc:Bounds height="32.0" width="32.0" x="275.0" y="455.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_2" targetElement="_3">
<omgdi:waypoint x="296.0" y="77.0"/>
<omgdi:waypoint x="296.0" y="140.0"/>
<bpmndi:BPMNLabel>
<omgdc: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="_3" targetElement="_4">
<omgdi:waypoint x="297.5" y="195.0"/>
<omgdi:waypoint x="297.5" y="245.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_4" targetElement="_5">
<omgdi:waypoint x="297.5" y="300.0"/>
<omgdi:waypoint x="297.5" y="350.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_5" targetElement="_6">
<omgdi:waypoint x="291.0" y="405.0"/>
<omgdi:waypoint x="291.0" y="455.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
对应的holiday.png
2.部署流程
单个文件部署方式
其实就是加载bpmn图,将流程相关信息加载到表中
---repositoryService
/**
* 部署流程(加载bpmn图,解析流程信息,将数据添加到对应的表中)
* 影响的表:
* act_re_procdef 流程定义的信息
* act_re_deployment 部署信息
* act_ge_bytearray 流程定义的bpmn文件及png文件
*/
@Test
public void test2() {
//创建ProcessEngine对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取repositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//部署
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("请假申请流程")
.deploy();
System.out.println(deploy.getId());
System.out.println(deploy.getName());
System.out.println(deploy.getKey());
}
压缩包方式部署
可以将所有的bpmn文件,png等文件放到压缩文件中,然后通过压缩包方式部署
3.启动一个流程实例
/**
* 启动流程实例
* 影响的表:
* act_hi_actinst 已完成的活动信息
* act_hi_identitylink 参与者信息
* act_hi_procinst 流程实例
* act_hi_taskinst 任务实例
* act_ru_execution 执行表
* act_ru_identitylink 参与者信息 任务
* act_ru_task
*/
@Test
public void test3() {//创建ProcessEngine对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
//启动流程实例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
//实例相关信息
System.out.println(processInstance.getDeploymentId());//部署id
System.out.println(processInstance.getId());//实例id
}
4.任务查询
@Test
public void test4() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
TaskService taskService = processEngine.getTaskService();
//查询用户任务列表
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey("holiday")
.taskAssignee("zhangsan")
.list();
for (Task task : list) {
System.out.println(task.getAssignee());//任务负责人
System.out.println(task.getId());//任务id
System.out.println(task.getName());
System.out.println(task.getProcessInstanceId());//流程实例id
}
}
5.任务处理
//处理任务
@Test
public void test5(){
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
TaskService taskService = processEngine.getTaskService();
//根据任务id 处理任务
taskService.complete("2505");
}
6.相关api
流程定义查询
@Test
//查询流程定义信息
public void test6(){
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
//流程定义查询器
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//根据版本号降序
List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("holiday")
.orderByProcessDefinitionVersion()
.desc().list();
for (ProcessDefinition processDefinition : list) {
System.out.println(processDefinition.getDeploymentId());
System.out.println(processDefinition.getId());
System.out.println(processDefinition.getKey());
System.out.println(processDefinition.getName());
}
}
流程定义删除
@Test
//流程定义删除
public void test7(){
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
//删除流程定义(根据流程定义id删除)
//影响的表和流程定义的那几张表一样
repositoryService.deleteDeployment("5001",true);
}
注意事項:
- 正在执行的流程没有结束的话,删除流程定义会失败
- 如果需要强制删除的话,用repositoryService.deleteDeployment("5001",true);,这个时候会先删除没有执行完的流程,再删除流程定义信息
流程定义资源查询
查询png图片 和 bpmn文件,应用场景:用户想看查看需要经历哪些流程
在act_ge_bytearray表中查询
方案:
- 使用activiti7的api实现
- 使用jdbc操作blob类型,clob类型数据(原理层面)
activiti7的api实现:
@Test
//流程定义资源查询
public void test8() throws IOException {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
//查询器
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//查询流程定义信息
ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey("holiday").singleResult();
String deploymentId = processDefinition.getDeploymentId();//流程部署id
//查询读取资源文件 bpmn png等 ,读取到输入流
//两个参数:部署id,资源名称
InputStream bpmnIs = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
InputStream pngIs = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
//输出到指定目录
FileOutputStream bpmnFis = new FileOutputStream("D:\\文件下载\\"+processDefinition.getDiagramResourceName()); //bpmn文件名\
FileOutputStream pngFis = new FileOutputStream("D:\\文件下载\\"+processDefinition.getResourceName());//png文件名
byte[] bytes = new byte[1024];
int len;
while ((len=bpmnIs.read(bytes))!=-1){
bpmnFis.write(bytes,0,len);
}
while ((len=pngIs.read(bytes))!=-1){
pngFis.write(bytes,0,len);
}
bpmnIs.close();
bpmnFis.close();
pngFis.close();
pngIs.close();
}
历史信息查询
历史信息包括 正在进行的任务和已经完成的任务
@Test
//历史信息查询
public void test9(){
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
//查询器
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
//查询 根据开始时间升序
historicActivityInstanceQuery.processInstanceId("7501");//流程实例id
List<HistoricActivityInstance> list = historicActivityInstanceQuery.orderByHistoricActivityInstanceStartTime().asc().list();
for (HistoricActivityInstance historicActivityInstance : list) {
System.out.println(historicActivityInstance.getActivityId());//任务定义的key
System.out.println(historicActivityInstance.getActivityName());//任务名称
System.out.println(historicActivityInstance.getAssignee());//责任人
System.out.println(historicActivityInstance.getId());//任务id
System.out.println(historicActivityInstance.getProcessInstanceId());//实例id
System.out.println(historicActivityInstance.getProcessDefinitionId());//流程定义id
}
}
标签:activiti,流程,基础,System,Activiti7,println,processEngine,out
From: https://www.cnblogs.com/cutesheep/p/16915252.html