当前位置:网站首页>Activiti7工作流的使用
Activiti7工作流的使用
2022-07-06 09:00:00 【java领域】
1 Activiti服务架构#
1.1 概述#
1.2 activiti-cfg.xml#
- activiti-cfg.xml是activiti的引擎配置文件,包括:ProcessEngineConfiguration的定义、数据源的定义、事务管理器等,此文件其实就是一个Spring配置文件,下面是一个基本的配置只配置了ProcessEngineConfiguration和数据源。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="url"
value="jdbc:mysql://192.168.134.100:3306/activiti?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"/>
<property name="password" value="123456"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<!-- Activiti单独运行的ProcessEngine配置 -->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
<!--
activiti数据库表处理策略
false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常
true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。
create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。
drop-create:先删除表再创建表。
create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表
-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
1.3 ProcessEngineConfiguration#
1.3.1 概述#
- 流程引擎的配置类,通过ProcessEngineConfiguration可以创建工作流引擎ProcessEngine,常用的两种方法如下:
1.3.2 StandaloneProcessEngineConfiguration#
- 通过org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration,Activiti可以单独运行,使用它创建的ProcessEngine,Activiti会自己处理事务。
- 配置文件方式:
- 通常在activiti-cfg.xml配置文件中定义一个id为processEngineConfiguration的Bean,这里会使用Spring的依赖注入来构建引擎。
- <!-- Activiti单独运行的ProcessEngine配置 --> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- 数据源 --> <property name="dataSource" ref="dataSource"/> <!-- activiti数据库表处理策略 false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常 true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。 create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。 drop-create:先删除表再创建表。 create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表 --> <property name="databaseSchemaUpdate" value="true"/> </bean>
1.3.3 SpringProcessEngineConfiguration#
- 通过org.activiti.spring.SpringProcessEngineConfiguration和Spring整合。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="url"
value="jdbc:mysql://192.168.134.100:3306/activiti?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"/>
<property name="password" value="123456"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<!-- 工作流引擎配置bean -->
<bean id="processEngineConfiguration"
class="org.activiti.spring.SpringProcessEngineConfiguration">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 使用spring事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 数据库策略 -->
<property name="databaseSchemaUpdate" value="drop-create"/>
</bean>
<!-- 流程引擎 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration"
ref="processEngineConfiguration"/>
</bean>
<!-- 资源服务service -->
<bean id="repositoryService" factory-bean="processEngine"
factory-method="getRepositoryService" />
<!-- 流程运行service -->
<bean id="runtimeService" factory-bean="processEngine"
factory-method="getRuntimeService" />
<!-- 任务管理service -->
<bean id="taskService" factory-bean="processEngine"
factory-method="getTaskService" />
<!-- 历史管理service -->
<bean id="historyService" factory-bean="processEngine"
factory-method="getHistoryService" />
<!-- 引擎管理service -->
<bean id="managementService" factory-bean="processEngine"
factory-method="getManagementService" />
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 -->
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 切面,根据具体项目修改切点配置 -->
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.sunxiaping.*.service.impl.*.*(..))" />
</aop:config>
</beans>
1.3.4 创建ProcessEngineConfiguration#
- 下面的方法:要求activiti-cfg.xml中必须由一个processEngineConfiguration的Bean的id。
public static ProcessEngineConfiguration createProcessEngineConfigurationFromResource(String resource) {
return createProcessEngineConfigurationFromResource(resource, "processEngineConfiguration");
}
- 下面的方法,可以更改Bean的id。
public static ProcessEngineConfiguration createProcessEngineConfigurationFromResource(String resource, String beanName) {
return BeansConfigurationHelper.parseProcessEngineConfigurationFromResource(resource, beanName);
}
1.4 ProcessEngine#
- 工作流引擎,相当于一个门面接口,通过ProcessEngineConfiguration创建ProcessEngine,通过ProcessEngine创建各个Service接口。
1.4.1 一般创建方式#
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 6:41
*/
public class ActivitiTest {
public static void main(String[] args) {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//创建ProcessEngine对象
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println("processEngine = " + processEngine);
}
}
1.4.2 简单创建方式#
- 将activiti.cfg.xml文件名以及路径固定,且activiti.cfg.xml文件中有processEngineConfiguration的配置,那么可以使用如下代码创建ProcessEngine。
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 6:41
*/
public class ActivitiTest {
public static void main(String[] args) {
//该方法有限制
//①Activiti的配置文件名必须为activiti.cfg.xml
//②Bean的id必须是processEngineConfiguration
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println("processEngine = " + processEngine);
}
}
1.5 Service#
1.5.1 Service的创建方式#
- 通过ProcessEngine创建Service,Service是工作流引擎提供用于进行工作流部署、指定、管理的服务接口。
- 创建方式如下:
package com.sunxiaping;
import org.activiti.engine.*;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiTest {
public static void main(String[] args) {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
//创建ProcessEngine对象
ProcessEngine processEngine = configuration.buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
ManagementService managementService = processEngine.getManagementService();
System.out.println("repositoryService = " + repositoryService);
System.out.println("runtimeService = " + runtimeService);
System.out.println("taskService = " + taskService);
System.out.println("historyService = " + historyService);
System.out.println("managementService = " + managementService);
}
}
1.5.2 Service总览#
Service接口 | 说明 |
RepositoryService | Activiti的资源管理接口 |
RuntimeService | Activiti的流程运行管理接口 |
TaskService | Activiti的任务管理接口 |
HistoryService | Activiti的历史管理接口 |
ManagementService | Activiti的引擎管理接口 |
1.5.3 RepositoryService#
- RepositoryService,是Activiti的资源管理接口,提供了管理和控制流程发布包和流程定义的操作。使用工作流建模工具设计的业务流程图需要使用此Service将流程定义文件的内容部署到计算机中。
- 除了流程部署定义以外还可以做如下的操作:1️⃣查询引擎中的发布包和流程定义。2️⃣暂停或激活发布包以及对应全部和特定流程定义。暂停意味着它们不能再在执行任务操作了,激活是对应的反向操作。3️⃣获取多种资源,像包含在发布包中的文件获引擎自动生成的流程图。4️⃣获取流程定义的POJO,可以用解析流程,而不必通过XML。
1.5.4 RuntimeService#
- RuntimeService是Activiti的流程运行管理接口,可以从这个接口中获取很多关于流程执行相关的信息。
1.5.5 TaskService#
- TaskService是Activiti的任务管理接口,可以从这个接口中获取任务的信息。
1.5.6 HistoryService#
- HistoryService是Activiti的历史管理类,可以查询历史信息,执行流程时,引擎会包含很多数据(根据配置),比如流程实例启动时间,任务的参与者,完成任务的时间,每个流程实例的执行路径,等等。
1.5.7 ManagementService#
- ManagementService是Activiti的引擎管理接口,提供了对Activiti流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于Activiti系统的日常维护。
2 Activiti入门体验#
2.1 流程定义#
2.1.1 画板#
- 在IDEA中安装对应的Activiti-Designer(Activiti设计器)插件即可使用,画板中包括以下结点:
- Connection--连接。
- Event--事件。
- Task--任务。
- Gateway--网关。
- Container--容器。
- Boundary event--边界事件。
- Intermediate event--中间事件。
- 流程图设计完毕保存生成.bpmn文件。
- 本人此时使用的IDEA版本是2020.2,而IDEA中的Activiti设计器插件actiBPM到此时位置已停止更新了。
- 本人只能使用Eclipse画流程图。Eclipse需要安装Activiti插件,略。
2.1.2 绘制流程#
2.1.3 指定流程定义key#
- 流程定义key即流程定义的标识。
建议:相同的业务流程,流程定义的key名字定义一样。如果需要创建新的业务流程,则使用新的key。
2.1.4 指定任务负责人#
- 为每个任务结点指定负责人,如添加请假单的负责人是张三。
2.2 部署流程定义#
- 将刚才生成的holiday.bpmn和holiday.png拷贝到项目的resources目录下。
- 示例:使用RepositoryService部署流程定义
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiDeploymentTest {
/**
* 部署流程定义:将下面代码中指定的bpmn文件和png文件保存到Activiti数据库中
*
* act_re_deployment 部署信息
* act_re_procdef 流程定义的一些信息
* act_ge_bytearray 流程定义bpmn文件和png文件
*/
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//进行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn") //添加bpmn资源
.addClasspathResource("diagram/holiday.png")
.name("请假申请流程")
.deploy(); //部署
//输出部署的一些信息
String id = deployment.getId();
System.out.println("流程部署id = " + id);
String name = deployment.getName();
System.out.println("流程部署名称 = " + name);
}
}
2.3 启动一个流程实例#
- 流程定义部署在Activiti中之后就可以通过工作流管理业务流程了。
- 针对该流程,启动一个流程表示发起一个新的请假申请单,这就相当于Java类和Java对象的关系,类定义好之后需要new创建一个对象使用,当然,也可以new多个对象。
- 对于请假申请流程,张三发起一个请假申请单需要启动一个流程实例,李四发起一个请求申请单也需要启动一个流程实例。
关系:
流程定义(BPMN文件)-->流程部署(Activiti的三张表)。
流程实例-->启动流程实例。
类比:
流程定义类似于Java中的类,流程实例类似于Java中的一个实例(对象),所以一个流程定义key对应多个不同的流程实例。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 14:35
*/
public class ActivitiStartProcessInstanceTest {
/**
* act_hi_actinst 活动实例
* act_hi_identitylink 参与者信息
* act_hi_procinst 流程实例
* act_hi_taskinst 任务实例
* act_ru_execution 执行表
* act_ru_identitylink 参与者信息
* act_ru_task 任务表
*/
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RuntimeService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//根据流程定义的key启动流程实例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
//获取流程实例的相关信息
String processDefinitionId = processInstance.getProcessDefinitionId();
System.out.println("流程定义的id = " + processDefinitionId);
String deploymentId = processInstance.getDeploymentId();
System.out.println("流程部署的id = " + deploymentId);
String id = processInstance.getId();
System.out.println("流程实例的id = " + id);
String activityId = processInstance.getActivityId();
System.out.println("当前活动的id = " + activityId);
}
}
2.4 任务查询#
- 流程启动后,各个任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 15:00
*/
public class ActivitiTaskTest {
/**
* act_ru_task
*/
@Test
public void test() {
//任务负责人
String assignee = "张三";
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取TaskService对象
TaskService taskService = processEngine.getTaskService();
//查询任务列表,根据流程定义的key和任务负责人
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey("holiday").taskAssignee(assignee).list();
//遍历任务列表
for (Task task : taskList) {
String processDefinitionId = task.getProcessDefinitionId();
System.out.println("流程定义id = " + processDefinitionId);
String processInstanceId = task.getProcessInstanceId();
System.out.println("流程实例id = " + processInstanceId);
String assignee1 = task.getAssignee();
System.out.println("任务负责人 = " + assignee1);
String id = task.getId();
System.out.println("任务id = " + id);
String name = task.getName();
System.out.println("任务名称 = " + name);
}
}
}
2.5 任务处理#
- 任务负责人查询待办任务,选择任务进行处理,完成任务。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 15:20
*/
public class ActivitiTaskCompleteTest {
/**
* act_hi_actinst 活动实例
* act_hi_identitylink 参与者信息
* act_hi_taskinst 任务实例
* act_ru_execution 执行表
* act_ru_identitylink 参与者信息
* act_ru_task 任务表
*/
@Test
public void test() {
//任务负责人
String assignee = "张三";
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取TaskService对象
TaskService taskService = processEngine.getTaskService();
//查询任务列表,根据流程定义的key和任务负责人
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey("holiday").taskAssignee(assignee).list();
//遍历任务列表
for (Task task : taskList) {
String id = task.getId();
//完成任务
taskService.complete(id);
}
}
}
3 流程定义#
3.1 流程定义概述#
3.1.1 什么是流程定义?#
- 流程定义是按照BPMN2.0标准去描述业务流程,通常使用Activiti-explorer(Activiti控制台)或Activiti-eclipse-designer(Activiti的eclipse设计器)插件对业务流程进行建模,这两种方式都遵循BPMN2.0标准。
- 如果使用Activiti-eclipse-designer插件完成业务流程建模。可以生成两个文件:.bpmn和.png文件。
3.1.2 bpmn文件#
- .bpmn文件其实就是XML文件。
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="holiday" name="请假申请流程" isExecutable="true">
<startEvent id="startevent2" name="开始"/>
<userTask id="usertask1" name="填写请假申请单" activiti:assignee="张三"/>
<sequenceFlow id="flow1" sourceRef="startevent2" targetRef="usertask1"/>
<userTask id="usertask2" name="部门经理审批" activiti:assignee="李四"/>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"/>
<userTask id="usertask3" name="总经理审批" activiti:assignee="王五"/>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"/>
<endEvent id="endevent1" name="结束"/>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_holiday">
<bpmndi:BPMNPlane bpmnElement="holiday" id="BPMNPlane_holiday">
<bpmndi:BPMNShape bpmnElement="startevent2" id="BPMNShape_startevent2">
<omgdc:Bounds height="35.0" width="35.0" x="100.0" y="160.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="180.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="330.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="480.0" y="150.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="630.0" y="160.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="135.0" y="177.0"/>
<omgdi:waypoint x="180.0" y="177.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="285.0" y="177.0"/>
<omgdi:waypoint x="330.0" y="177.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="435.0" y="177.0"/>
<omgdi:waypoint x="480.0" y="177.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="585.0" y="177.0"/>
<omgdi:waypoint x="630.0" y="177.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
- .bpmn文件的根节点是definitions节点。这个元素中,可以定义多个流程定义(建议每个文件只包含一个流程定义,可以简化开发过程中的维护难度)。注意,definitions元素最少也要包含xmlns和targetNamespace的声明。targetNamespace可以是任何值,它用来对流程实例进行分类。
- 流程定义部分:定义了流程每个结点的描述和结点之间的流程流转。
- 流程布局定义:定义流程每个结点在流程图上的位置坐标等信息。
3.1.3 png图片文件#
- 如果是在Eclipse中,需要进行如下的配置:
3.2 流程定义部署#
3.2.1 什么是流程定义部署#
- 将生成的流程定义部署到Activiti的数据库中,这就是流程定义部署,通过调用Activiti的API将流程定义的bpmn和png两个文件一个一个添加部署到Activiti中,也可以将两个文件打成zip包进行部署。
3.2.2 单个文件部署方式#
- 分别将bpmn文件和png图片文件部署。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiDeploymentTest {
/**
* 部署流程定义:将下面代码中指定的bpmn文件和png文件保存到Activiti数据库中
*
* act_re_deployment 部署信息
* act_re_procdef 流程定义的一些信息
* act_ge_bytearray 流程定义bpmn文件和png文件
*/
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//进行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn") //添加bpmn资源
.addClasspathResource("diagram/holiday.png")
.name("请假申请流程")
.deploy(); //部署
//输出部署的一些信息
String id = deployment.getId();
System.out.println("流程部署id = " + id);
String name = deployment.getName();
System.out.println("流程部署名称 = " + name);
}
}
3.2.3 压缩包部署方式#
- 将.bpmn文件和.png图片压缩成一个zip包。
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
import java.io.InputStream;
import java.util.zip.ZipInputStream;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-07-31 11:55
*/
public class ActivitiZipDeploymentTest {
/**
* 部署流程定义:将下面代码中指定的bpmn文件和png文件保存到Activiti数据库中
*
* act_re_deployment 部署信息
* act_re_procdef 流程定义的一些信息
* act_ge_bytearray 流程定义bpmn文件和png文件
*/
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("diagram/holiday.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
//进行部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.name("请假申请流程")
.deploy(); //部署
//输出部署的一些信息
String id = deployment.getId();
System.out.println("流程部署id = " + id);
String name = deployment.getName();
System.out.println("流程部署名称 = " + name);
}
}
3.2.4 操作数据表#
- 流程定义部署后,会操作三张表:act_re_deployment、act_re_procdef和act_ge_bytearray。
- act_re_deployment是流程定义部署表,记录流程部署信息。
- act_re_procdef是流程定义表,记录流程定义信息。
- act_ge_bytearray是资源表,将.bpmn文件和.png图片存入到这个表。
说明:
act_re_deployment和act_re_procdef是一对多的关系,一次部署在流程部署表生成一条记录,但一次流程部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。每一个流程定义在act_ge_bytearray会存在两个资源记录.bpmn文件和.png图片。
建议:
一次部署一个流程,这样部署表和流程定义表示一对一的关系,方便读取流程部署和流程定义信息。
3.3 流程定义查询#
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 21:24
*/
public class ActivitiProcessDefinitionQueryTest {
/**
* 查询流程定义信息
*/
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//得到ProcessDefinitionQuery对象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//设置条件,并查询出当前的所有流程定义
List<ProcessDefinition> processDefinitionList = processDefinitionQuery.processDefinitionKey("holiday")
.orderByProcessDefinitionVersion()
.desc()
.list();
//输出流程定义信息
for (ProcessDefinition processDefinition : processDefinitionList) {
System.out.println("流程定义的id = " + processDefinition.getId());
System.out.println("流程定义的name = " + processDefinition.getName());
System.out.println("流程定义的key = " + processDefinition.getKey());
System.out.println("流程定义的version = " + processDefinition.getVersion());
}
}
}
3.4 流程定义删除#
- 示例:
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.junit.Test;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 21:13
*/
public class ActivitiDeleteProcessDefinitionTest {
/**
* 删除已经部署的流程定义
*
* 注意事项:
* ①当我们正在执行的这一套流程没有结束,此时如果要删除流程定义信息就会失败(调用void deleteDeployment(String deploymentId)方法)。
* ②当我们正在执行的这一套流程没有结束,此时如果要强制删除流程定义信息,需要调用void deleteDeployment(String deploymentId, boolean cascade)这个方式,将cascade设置为true。
*/
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//删除已经部署的流程定义
String deploymentId = "1";
repositoryService.deleteDeployment(deploymentId);
}
}
3.5 流程定义资源查询#
- 示例:通过查询流程定义对象获取流程定义资源,即bpmn和png
package com.sunxiaping;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.junit.Test;
import org.springframework.util.FileCopyUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-02 10:22
*/
public class ActivitiResourceTest {
@Test
public void test() throws IOException {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取ProcessDefinitionQuery对象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//设置查询条件,执行查询操作
List<ProcessDefinition> processDefinitionList = processDefinitionQuery.processDefinitionKey("holiday").orderByProcessDefinitionVersion().desc().list();
//遍历查询结果
for (ProcessDefinition processDefinition : processDefinitionList) {
//获取资源名称,即png图片的名称
String resourceName = processDefinition.getResourceName();
//获取图表资源,即bpmn图片的名称
String diagramResourceName = processDefinition.getDiagramResourceName();
//获取资源的输入流,即png图片的输入流
InputStream resourceNameInputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
InputStream diagramResourceNameInputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);
String resourcePath = "d:" + File.separator + resourceName;
File file = new File(resourcePath);
if (!file.exists()) {
file.getParentFile().mkdirs();
}
String diagramResourcePath = "d:" + File.separator + diagramResourceName;
file = new File(diagramResourcePath);
if (!file.exists()) {
file.getParentFile().mkdirs();
}
//复制文件
FileCopyUtils.copy(resourceNameInputStream, new FileOutputStream(resourcePath));
FileCopyUtils.copy(diagramResourceNameInputStream, new FileOutputStream(diagramResourcePath));
}
}
}
3.6 流程历史信息查询#
- 示例:
package com.sunxiaping;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.junit.Test;
import java.util.List;
/**
* @author <a href="mailto:[email protected]">weiwei.xu</a>
* @version 1.0
* 2020-08-01 21:13
*/
public class ActivitiHistoryTest {
@Test
public void test() {
//创建ProcessEngineConfiguration对象
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
//获取ProcessEngine对象
ProcessEngine processEngine = configuration.buildProcessEngine();
//获取HistoryService对象
HistoryService historyService = processEngine.getHistoryService();
//获取HistoricActivityInstanceQuery查询对象
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
List<HistoricActivityInstance> historicActivityInstanceList = historicActivityInstanceQuery.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
String activityId = historicActivityInstance.getActivityId();
System.out.println("activityId = " + activityId);
String activityName = historicActivityInstance.getActivityName();
System.out.println("activityName = " + activityName);
String processDefinitionId = historicActivityInstance.getProcessDefinitionId();
System.out.println("processDefinitionId = " + processDefinitionId);
String processInstanceId = historicActivityInstance.getProcessInstanceId();
System.out.println("processInstanceId = " + processInstanceId);
}
}
}
如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
咱们下期见!学习更多JAVA知识与技巧(获取原文),关注与私信博主(666)
边栏推荐
- Kratos战神微服务框架(二)
- Global and Chinese markets for small seed seeders 2022-2028: Research Report on technology, participants, trends, market size and share
- The carousel component of ant design calls prev and next methods in TS (typescript) environment
- go-redis之初始化連接
- LeetCode:221. Largest Square
- What is an R-value reference and what is the difference between it and an l-value?
- 不同的数据驱动代码执行相同的测试场景
- [oc]- < getting started with UI> -- common controls - prompt dialog box and wait for the prompt (circle)
- 在QWidget上实现窗口阻塞
- [shell script] use menu commands to build scripts for creating folders in the cluster
猜你喜欢
Improved deep embedded clustering with local structure preservation (Idec)
Advance Computer Network Review(1)——FatTree
[oc]- < getting started with UI> -- learning common controls
注意力机制的一种卷积替代方式
自定义卷积注意力算子的CUDA实现
Reids之删除策略
BN折叠及其量化
Digital people anchor 618 sign language with goods, convenient for 27.8 million people with hearing impairment
Master slave replication of redis
KDD 2022论文合集(持续更新中)
随机推荐
Nacos installation and service registration
Advanced Computer Network Review(4)——Congestion Control of MPTCP
QML type: locale, date
Five layer network architecture
LeetCode:394. String decoding
In depth analysis and encapsulation call of requests
AcWing 2456. Notepad
甘肃旅游产品预订增四倍:“绿马”走红,甘肃博物馆周边民宿一房难求
LeetCode41——First Missing Positive——hashing in place & swap
Multivariate cluster analysis
LeetCode:34. Find the first and last positions of elements in a sorted array
使用标签模板解决用户恶意输入的问题
Global and Chinese market for annunciator panels 2022-2028: Research Report on technology, participants, trends, market size and share
Heap (priority queue) topic
Selenium+pytest automated test framework practice
IJCAI2022论文合集(持续更新中)
[oc]- < getting started with UI> -- learning common controls
Reids之删除策略
数字人主播618手语带货,便捷2780万名听障人士
Advanced Computer Network Review(5)——COPE