Activiti的使用
1.部署activiti
2.流程定义
3.流程定义部署
4.启动流程实例
5.用户查询代办任务
6.用户办理任务
7.流程结束
请假审批流程
填写请假申请 -->部门经理审批 -->总经理审批
搭建环境
Activiti 7.0.0.Beta1 +jdk1.8 +mysql 5.7
pom.xml
1 <properties> 2 <slf4j.version>1.6.6</slf4j.version> 3 <log4j.version>1.2.12</log4j.version> 4 </properties> 5 6 <dependencies> 7 8 <dependency> 9 <groupId>org.activiti</groupId> 10 <artifactId>activiti-engine</artifactId> 11 <version>7.0.0.Beta1</version> 12 </dependency> 13 14 <dependency> 15 <groupId>org.activiti</groupId> 16 <artifactId>activiti-spring</artifactId> 17 <version>7.0.0.Beta1</version> 18 </dependency> 19 20 <dependency> 21 <groupId>org.activiti</groupId> 22 <artifactId>activiti-bpmn-model</artifactId> 23 <version>7.0.0.Beta1</version> 24 </dependency> 25 26 <dependency> 27 <groupId>org.activiti</groupId> 28 <artifactId>activiti-bpmn-converter</artifactId> 29 <version>7.0.0.Beta1</version> 30 </dependency> 31 32 <dependency> 33 <groupId>org.activiti</groupId> 34 <artifactId>activiti-json-converter</artifactId> 35 <version>7.0.0.Beta1</version> 36 </dependency> 37 38 <dependency> 39 <groupId>org.activiti</groupId> 40 <artifactId>activiti-bpmn-layout</artifactId> 41 <version>7.0.0.Beta1</version> 42 </dependency> 43 44 <dependency> 45 <groupId>org.activiti.cloud</groupId> 46 <artifactId>activiti-cloud-services-api</artifactId> 47 <version>7.0.0.Beta1</version> 48 </dependency> 49 50 <dependency> 51 <groupId>mysql</groupId> 52 <artifactId>mysql-connector-java</artifactId> 53 <version>5.1.40</version> 54 </dependency> 55 56 <dependency> 57 <groupId>junit</groupId> 58 <artifactId>junit</artifactId> 59 <version>4.12</version> 60 </dependency> 61 62 <!-- log start --> 63 <dependency> 64 <groupId>log4j</groupId> 65 <artifactId>log4j</artifactId> 66 <version>${log4j.version}</version> 67 </dependency> 68 <dependency> 69 <groupId>org.slf4j</groupId> 70 <artifactId>slf4j-api</artifactId> 71 <version>${slf4j.version}</version> 72 </dependency> 73 <dependency> 74 <groupId>org.slf4j</groupId> 75 <artifactId>slf4j-log4j12</artifactId> 76 <version>${slf4j.version}</version> 77 </dependency> 78 <!-- log end --> 79 80 <dependency> 81 <groupId>org.mybatis</groupId> 82 <artifactId>mybatis</artifactId> 83 <version>3.4.5</version> 84 </dependency> 85 86 <dependency> 87 <groupId>commons-dbcp</groupId> 88 <artifactId>commons-dbcp</artifactId> 89 <version>1.4</version> 90 </dependency> 91 92 </dependencies> 93 94 95 96 <repositories> 97 <repository> 98 <id>alfresco</id> 99 <name>Activiti Releases</name> 100 <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url> 101 <releases> 102 <enabled>true</enabled> 103 </releases> 104 </repository> 105 </repositories>
activiti.cfg.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/contex http://www.springframework.org/schema/context/spring-context.xsd 8 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 9 10 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 11 <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 12 <property name="url" value="jdbc:mysql://localhost:3306/activiti" /> 13 <property name="username" value="root" /> 14 <property name="password" value="root" /> 15 <property name="maxActive" value="3" /> 16 <property name="maxIdle" value="1" /> 17 </bean> 18 19 <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> 20 <property name="dataSource" ref="dataSource"></property> 21 <property name="databaseSchemaUpdate" value="true"/> 22 </bean> 23 24 25 </beans>
配置数据源和processEngineConfiguration
processEngineConfiguration 用来创建ProcessEngine
databaseSchemaUpdate 数据表的设计策略
false(默认):检查数据库表的版本和依赖库的版本, 如果版本不匹配就抛出异常。
true: 构建流程引擎时,执行检查,如果需要就执行更新。 如果表不存在,就创建。
create-drop: 构建流程引擎时创建数据库表, 关闭流程引擎时删除这些表。
drop-create:先删除表再创建表。
create: 构建流程引擎时创建数据库表, 关闭流程引擎时不删除这些表
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 # LOGFILE is set to be a File appender using a PatternLayout. log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:axis.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
创建数据库
1 public void testGenTable(){ 2 //创建processEngineConfiguration 3 ProcessEngineConfiguration configuration = 4 ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml"); 5 6 //创建ProcessEngine 7 ProcessEngine processEngine = configuration.buildProcessEngine(); 8 9 System.out.println(processEngine); 10 11 }
创建25张表
Activiti 的表都以 ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的 API 对
应。
ACT_RE_*: 'RE'表示 repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,
规则,等等)。
ACT_RU_*: 'RU'表示 runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,
等运行中的数据。 Activiti 只在流程实例执行过程中保存这些数据, 在流程结束时就会删
除这些记录。 这样运行时表可以一直很小速度很快。
ACT_HI_*: 'HI'表示 history。 这些表包含历史数据,比如历史流程实例, 变量,任务等
等。
ACT_GE_*: GE 表示 general。 通用数据, 用于不同场景下
架构图
Service
Service 是工作流引擎提供用于进行工作流部署、执行、管理的服务接口
RepositoryService | activiti 的资源管理类 |
RuntimeService | activiti 的流程运行管理类 |
TaskService | activiti 的任务管理类 |
HistoryService | activiti 的历史管理类 |
ManagerService | activiti 的引擎管理类 |
创建bpmn文件
1 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 2 <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"> 3 <process id="holiday" isClosed="false" isExecutable="true" name="请假流程" processType="None"> 4 <startEvent id="_2" name="StartEvent"/> 5 <userTask activiti:assignee="zhangsan" activiti:exclusive="true" id="_3" name="填写请假申请单"/> 6 <userTask activiti:assignee="lishi" activiti:exclusive="true" id="_4" name="部门经理审批"/> 7 <userTask activiti:assignee="wangwu" activiti:exclusive="true" id="_5" name="总经理审批"/> 8 <endEvent id="_6" name="EndEvent"/> 9 <sequenceFlow id="_7" sourceRef="_2" targetRef="_3"/> 10 <sequenceFlow id="_8" sourceRef="_3" targetRef="_4"/> 11 <sequenceFlow id="_9" sourceRef="_4" targetRef="_5"/> 12 <sequenceFlow id="_10" sourceRef="_5" targetRef="_6"/> 13 </process> 14 <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"> 15 <bpmndi:BPMNPlane bpmnElement="holiday"> 16 <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2"> 17 <omgdc:Bounds height="32.0" width="32.0" x="280.0" y="45.0"/> 18 <bpmndi:BPMNLabel> 19 <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> 20 </bpmndi:BPMNLabel> 21 </bpmndi:BPMNShape> 22 <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3"> 23 <omgdc:Bounds height="55.0" width="85.0" x="255.0" y="140.0"/> 24 <bpmndi:BPMNLabel> 25 <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> 26 </bpmndi:BPMNLabel> 27 </bpmndi:BPMNShape> 28 <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4"> 29 <omgdc:Bounds height="55.0" width="85.0" x="255.0" y="245.0"/> 30 <bpmndi:BPMNLabel> 31 <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> 32 </bpmndi:BPMNLabel> 33 </bpmndi:BPMNShape> 34 <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5"> 35 <omgdc:Bounds height="55.0" width="85.0" x="255.0" y="350.0"/> 36 <bpmndi:BPMNLabel> 37 <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> 38 </bpmndi:BPMNLabel> 39 </bpmndi:BPMNShape> 40 <bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6"> 41 <omgdc:Bounds height="32.0" width="32.0" x="275.0" y="455.0"/> 42 <bpmndi:BPMNLabel> 43 <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> 44 </bpmndi:BPMNLabel> 45 </bpmndi:BPMNShape> 46 <bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_2" targetElement="_3"> 47 <omgdi:waypoint x="296.0" y="77.0"/> 48 <omgdi:waypoint x="296.0" y="140.0"/> 49 <bpmndi:BPMNLabel> 50 <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> 51 </bpmndi:BPMNLabel> 52 </bpmndi:BPMNEdge> 53 <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_3" targetElement="_4"> 54 <omgdi:waypoint x="297.5" y="195.0"/> 55 <omgdi:waypoint x="297.5" y="245.0"/> 56 <bpmndi:BPMNLabel> 57 <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> 58 </bpmndi:BPMNLabel> 59 </bpmndi:BPMNEdge> 60 <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_4" targetElement="_5"> 61 <omgdi:waypoint x="297.5" y="300.0"/> 62 <omgdi:waypoint x="297.5" y="350.0"/> 63 <bpmndi:BPMNLabel> 64 <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> 65 </bpmndi:BPMNLabel> 66 </bpmndi:BPMNEdge> 67 <bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_5" targetElement="_6"> 68 <omgdi:waypoint x="291.0" y="405.0"/> 69 <omgdi:waypoint x="291.0" y="455.0"/> 70 <bpmndi:BPMNLabel> 71 <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> 72 </bpmndi:BPMNLabel> 73 </bpmndi:BPMNEdge> 74 </bpmndi:BPMNPlane> 75 </bpmndi:BPMNDiagram> 76 </definitions>
流程定义
public static void main(String[] args) { //1.创建ProcessEngine对象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //2.得到RepositoryService实例 RepositoryService repositoryService = processEngine.getRepositoryService(); //3.进行部署 Deployment deployment = repositoryService.createDeployment() .addClasspathResource("diagram/holiday.bpmn") //添加bpmn资源 .addClasspathResource("diagram/holiday.png") .name("请假申请单流程") .deploy();
启动流程实例
1 /** 2 * 启动流程实例 3 * 1.得到ProcessEngine对象 4 * 2.得到RuntimeService对象 5 * 3.创建流程实例,需要知道流程定义的key 6 * 7 * 背后影响的表 8 * act_hi_actinst 已完成的活动信息 9 * act_hi_identifylink 参与者计划 10 * act_hi_procinst 流程实例 11 * act_hi_taskinst 任务实例 12 * act_ru_execution 执行表 13 * act_ru_identitylink 参与者信息 14 * act_ru_task 任务 15 * 16 */ 17 public class ActivitiStartInstance { 18 19 public static void main(String[] args) { 20 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 21 RuntimeService runtimeService = processEngine.getRuntimeService(); 22 runtimeService.startProcessInstanceByKey("hoilday"); 23 24 } 25 26 }
任务查询
/** * 查询当前用户的任务列表 * 1.得到ProcessEngine * 2.得到taskService对象 * 3.根据流程定义id的key,负责人assigine来表示当前用户列表查询 * 4.任务列表的展示 */ public class TaskQuery { public static void main(String[] args) { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery() .processDefinitionKey("hoilday") .taskAssignee("lisi") .singleResult(); System.out.println("流程实例ID"+task.getProcessInstanceId()); System.out.println("任务ID"+task.getId()); System.out.println("任务负责人"+task.getAssignee()); System.out.println("任务名称"+task.getName()); } }
任务处理
public class TaskComplete { public static void main(String[] args) { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); taskService.complete("17502"); //任务查询的ID } }
合并任务查询和处理工作
/** * 合并任务查询和任务处理工作 * @param args */ public static void main(String[] args) { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery().processDefinitionKey("holiday").taskAssignee("wangwu").singleResult(); //处理任务,结合当前用户任务列表查询操作,任务ID taskService.complete(task.getId()); System.out.println(task.getId()); }
流程定义部署(压缩包方式)
将 holiday.bpmn 和 holiday.png 压缩成 zip 包
//流程定义部署 流程制作出来后要上传到服务器 zip文件更便于上传 public static void main(String[] args) { //1.创建ProcessEngine对象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //2.得到RepositoryService实例 RepositoryService repositoryService = processEngine.getRepositoryService(); //3.转化出ZipInputStream流对象 InputStream is = ActivitiDeployment.class.getClassLoader().getResourceAsStream("diagram/bpmn.zip"); //将 inputstream流转化为ZipInputStream流 ZipInputStream zipInputStream = new ZipInputStream(is); //3.进行部署 Deployment deployment = repositoryService.createDeployment() .addZipInputStream(zipInputStream) .name("请假申请单流程") .deploy(); //4.输出部署的一些信息 System.out.println(deployment.getName()); System.out.println(deployment.getId()); }
概述
ProcessEngineConfigiuration类加载activiti.cfg.xml配置文件
ProcessEngine类 得到Service接口
Service接口
部署流程定义实例
1.单文件 2.zip包
启动流程实例,RuntimeService startProcessInstanceByKey(" key")
查看任务 taskService.createTaskQuery()
完成任务 taskService.complate(task.getId())
删除流程定义
1 /** 2 * 3 * 删除已经部署的流程定义 4 * 1.得到ProcessEngine 5 * 2.创建RepositoryService 6 * 3.执行删除流程定义,参数为流程部署ID 7 * 8 当正在执行者一套没有完全审批结束的时候,此时要删除流程定义信息就会失败 9 强制删除,参数为true,代表级联删除 10 */ 11 public class DeleteProcessDefinition { 12 public static void main(String[] args) { 13 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 14 RepositoryService repositoryService = processEngine.getRepositoryService(); 15 repositoryService.deleteDeployment("12501"); //12501 16 17 } 18 }
流程定义资源查询
1 /** 2 * 查询流程定义信息 3 * 1.得到ProcessEngine 4 * 2.创建RepositoryService 5 * 3.得到ProcessDefinitionQuery 6 * 4.设置条件,查询出当前所有流程定义 ,流程定义的key 7 * 5.输出流程定义 8 */ 9 public class QueryProcessDefinition { 10 public static void main(String[] args) { 11 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 12 RepositoryService repositoryService = processEngine.getRepositoryService(); 13 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); 14 15 List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("请假流程").orderByProcessDefinitionVersion().desc().list(); 16 17 for (ProcessDefinition processDefinition : list){ 18 System.out.println("流程定义ID"+processDefinition.getId()); 19 System.out.println("流程定义id: " + processDefinition.getId()); 20 System.out.println("流程定义名称: " + processDefinition.getName()); 21 System.out.println("流程定义key: " + processDefinition.getKey()); 22 System.out.println("流程定义版本: " + processDefinition.getVersion()); 23 System.out.println("部署id"+ processDefinition.getDeploymentId()); 24 } 25 } 26 }
资源文件的保存
1 /** 2 * 需求:从act_bytearray表中读取文件,进行本地保存 3 * 4 * 场景:用户查看请假流程具体步骤 5 * 方案: 1activi的api 6 * 2.commmons-io 7 * 8 * 步骤: 9 * 1.得到processEngine 10 * 2.得到RepositoryService对象 11 * 3.得到查询器 :ProcessDefinitionQuery 12 * 4.设置查询条件 13 * 5.执行查询操作,查询出流程定义信息 14 * 6.通过流程定义信息,得到部署id 15 * 7.通过repositoryService方法,实现读取图片信息及bpmn文件信息 16 * -- getResourceAsStream (部署id ,资源名称) 17 * 8.构建出OutputStream流 18 * 9.实现输入流和输出流的转换 19 *10.关闭流 20 */ 21 public class QueryBpmn { 22 23 public static void main(String[] args) throws IOException { 24 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 25 RepositoryService repositoryService = processEngine.getRepositoryService(); 26 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); 27 processDefinitionQuery.processDefinitionKey("请假流程"); //参数是流程定义的key 28 ProcessDefinition processDefinition = processDefinitionQuery.singleResult(); 29 String deploymentId = processDefinition.getDeploymentId(); 30 InputStream pngIs = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName()); 31 InputStream bpmnIs = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName()); 32 33 OutputStream pngOs = 34 new FileOutputStream("D:\activiti\save\"+ processDefinition.getDiagramResourceName()); 35 36 OutputStream bpmnOs = 37 new FileOutputStream("D:\activiti\save\"+ processDefinition.getResourceName()); 38 39 IOUtils.copy(pngIs,pngOs); 40 IOUtils.copy(bpmnIs,bpmnOs); 41 42 43 pngOs.close(); 44 bpmnOs.close(); 45 pngIs.close(); 46 bpmnIs.close(); 47 48 49 } 50 }
历史信息的查询
定义已经删除了,流程执行的历史信息通过前面的分析,依然保存在 activiti 的 act_hi_*相关的表中
1 /** 2 * 历史信息查询 3 * 步骤 4 * 1.得到ProcessEngine 5 * 2.得到HistoryService 6 * 3.得到HistoryActvitiInstanceQuery 7 * 4.执行查询 8 * 5.遍历查询结果 9 */ 10 public class HistoryQuery { 11 12 public static void main(String[] args) { 13 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 14 HistoryService historyService = processEngine.getHistoryService(); 15 HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery(); 16 historicActivityInstanceQuery.processInstanceId("15001"); //设置流程实例ID 17 List<HistoricActivityInstance> list = historicActivityInstanceQuery.list(); 18 19 for (HistoricActivityInstance instance : list){ 20 System.out.println(instance.getActivityId()); 21 System.out.println(instance.getActivityName()); 22 System.out.println(instance.getProcessDefinitionId()); 23 System.out.println(instance.getProcessInstanceId()); 24 System.out.println("-------------------"); 25 } 26 27 28 } 29 30 }
完