Activiti工作流
1.简介
Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准。
Activiti是一种轻量级,可嵌入的BPM引擎,而且还设计适用于可扩展的云架构。 Activiti将提供宽松的Apache许可2.0,同时促进Activiti BPM引擎和BPMN 2.0的匹配。
2.Activiti的7大服务
RepositoryService:提供一系列管理流程部署和流程定义的API。
RuntimeService:在流程运行时对流程实例进行管理与控制。
TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。
IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。
ManagementService:提供对流程引擎进行管理和维护的服务。
HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。
FormService:表单服务。
3.应用实例
3.1.开发组件
名称 |
版本 |
HighGoDB |
安全版V4.5、企业版V5及以上 |
HgdbJdbc |
6.2.4 |
JDK |
1.6、1.7、1.8 |
Java IDE |
IntelliJ IDEA |
SpringBoot |
2.1.0.RELEASE |
Activiti |
7.0.0.Beta2 |
3.2.工程示例
3.3.主要文件
pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <version>7.0.0.Beta2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.highgo</groupId> <artifactId>HgdbJdbc</artifactId> <version>6.2.4</version> </dependency> </dependencies>
|
application.yml
spring: datasource: url: jdbc:highgo://xxxx:5866/activiti?currentSchema=activiti username : sysdba password : XXXX driver-class-name: com.highgo.jdbc.Driver activiti: database-schema-update: true check-process-definitions: false process-definition-location-prefix: classpath:/processes/ db-history-used: true history-level: full async-executor-activate: false
|
leave.bpmn20.xml
<?xml version="1.0" encoding="UTF-8"?> <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/processdef"> <process id="leave" name="leave" isExecutable="true"> <startEvent id="sid-4bb1b894-4189-4443-9d51-08408088e392"/> <userTask id="sid-76b385e0-c375-40af-afbe-9623fe40ee7f" name="部门经理审批" activiti:assignee="${bm}"/> <sequenceFlow id="sid-fbfc3fc7-99c7-46fd-9825-1f5d3fa6e82a" sourceRef="sid-4bb1b894-4189-4443-9d51-08408088e392" targetRef="sid-76b385e0-c375-40af-afbe-9623fe40ee7f"/> <userTask id="sid-4a6bd0e8-285a-4770-b49d-5fa2f8dc698b" name="总经理审批" activiti:assignee="${gm}"/> <sequenceFlow id="sid-d37f31eb-c958-4c5e-a834-3c48191d1091" sourceRef="sid-76b385e0-c375-40af-afbe-9623fe40ee7f" targetRef="sid-4a6bd0e8-285a-4770-b49d-5fa2f8dc698b"/> <endEvent id="sid-9e1a9189-9194-4a79-86ba-8dcbb2280e31"/> <sequenceFlow id="sid-b945400f-4bae-4f2e-b6e1-0d2083d4b028" sourceRef="sid-4a6bd0e8-285a-4770-b49d-5fa2f8dc698b" targetRef="sid-9e1a9189-9194-4a79-86ba-8dcbb2280e31"/> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_leave"> <bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave"> <bpmndi:BPMNShape id="shape-eaad1e5b-25df-445e-a846-7ed05e474f7e" bpmnElement="sid-4bb1b894-4189-4443-9d51-08408088e392"> <omgdc:Bounds x="-225.0" y="-60.0" width="30.0" height="30.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="shape-990f85eb-2522-47cf-963d-0f16efbe9011" bpmnElement="sid-76b385e0-c375-40af-afbe-9623fe40ee7f"> <omgdc:Bounds x="-130.0" y="-85.0" width="100.0" height="80.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="edge-b4d997db-6421-434c-b10f-285b7f28fc26" bpmnElement="sid-fbfc3fc7-99c7-46fd-9825-1f5d3fa6e82a"> <omgdi:waypoint x="-195.0" y="-45.0"/> <omgdi:waypoint x="-130.0" y="-45.0"/> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="shape-b3139f61-0389-4cd6-ba9a-da6f41b22e9c" bpmnElement="sid-4a6bd0e8-285a-4770-b49d-5fa2f8dc698b"> <omgdc:Bounds x="40.0" y="-85.0" width="100.0" height="80.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="edge-2676f501-c646-4be0-9f69-325b55e2384e" bpmnElement="sid-d37f31eb-c958-4c5e-a834-3c48191d1091"> <omgdi:waypoint x="-30.0" y="-45.0"/> <omgdi:waypoint x="40.0" y="-45.0"/> </bpmndi:BPMNEdge> <bpmndi:BPMNShape id="shape-55c9ee0f-8507-449d-abf2-459285170784" bpmnElement="sid-9e1a9189-9194-4a79-86ba-8dcbb2280e31"> <omgdc:Bounds x="195.0" y="-60.0" width="30.0" height="30.0"/> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="edge-ca8ae4f1-3bfd-4011-83e0-f864a8799213" bpmnElement="sid-b945400f-4bae-4f2e-b6e1-0d2083d4b028"> <omgdi:waypoint x="140.0" y="-45.0"/> <omgdi:waypoint x="195.0" y="-45.0"/> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>
|
3.4.流程部署
3.4.1.自动部署
当 check-process-definitions:true 配置true时则为自动部署,需要把流程文件放到/processes/文件夹下。
3.4.2.手动部署
@Test public void deployment(){ Deployment deployment = repositoryService.createDeployment() .name("请假流程") .addClasspathResource("processes/leave.bpmn20.xml") .deploy(); System.out.println("流程ID:"+deployment.getId()); System.out.println("流程名称:"+deployment.getName()); }
|
日志打印输出
查看数据库表act_ge_bytearray中会增加一条数据,对应的就是刚刚新增的流程。
查看act_re_deployment
查看act_re_procdef
3.5.开启流程
@Test public void startProcess(){ String processDefinitionKey = "leave"; String businessKey = "001"; Map<String,Object> map = new HashMap<>(); map.put("bm","张三"); ProcessInstance leave = runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey, map); System.out.println("流程id:"+leave.getProcessDefinitionId()); System.out.println("流程实例id:"+leave.getId()); System.out.println("当前活动id:"+leave.getActivityId()); }
|
日志打印
因为是刚开始流程,所以没有人需要处理,当前活动id为null。这时查看act_hi_actinst就可以看到下一个需要处理的人。
3.6.查询任务
@Test public void findTask(){ List<Task> taskList = taskService.createTaskQuery() .processDefinitionKey("leave") .taskAssignee("张三") .list(); for (Task task : taskList) { System.out.println("任务id:"+task.getId()); System.out.println("任务名称:"+task.getName()); System.out.println("任务负责人:"+task.getAssignee()); System.out.println("流程定义id:"+task.getProcessDefinitionId()); System.out.println("流程实例id:"+task.getProcessInstanceId()); System.out.println("任务创建时间:"+task.getCreateTime()); } }
|
查询的数据来自表act_ru_task,需要注意的是act_ru_task 表中的数据只有需要处理的任务,一但任务完成,则会删除已完成任务的数据。
3.7.处理任务
@Test public void dealTask(){ Map<String,Object> map = new HashMap<>(); map.put("gm","李四"); Task task = taskService.createTaskQuery() .processDefinitionKey("leave") .taskAssignee("张三") .singleResult(); taskService.complete(task.getId(),map); System.out.println("处理任务id:"+task.getId()); }
|
act_hi_actinst表中,处理时间已填充,并且添加了一下个处理人
act_ru_task表,zhangsan的数据不再了,新增了李四的数据
3.8.完成任务
任务处理只需重复执行上述方法即可,只是更改了任务的处理人,直至任务结束。
@Test public void dealTask2() { Task task = taskService.createTaskQuery() .processDefinitionKey("leave") .taskAssignee("李四") .singleResult(); taskService.complete(task.getId()); System.out.println("处理任务id:"+task.getId()); }
|
3.9.获取流程处理历史
@Test public void getHistoryList() { List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery() .processDefinitionId("leave:1:0079b147-ed6c-11ee-a186-64bc58439558") .list(); for (HistoricTaskInstance historicTaskInstance : list) { System.out.println("开始时间:" + historicTaskInstance.getStartTime()); System.out.println("流程名称:" + historicTaskInstance.getName()); System.out.println("处理人名称:" + historicTaskInstance.getAssignee()); System.out.println("结束时间:" + historicTaskInstance.getEndTime()); } }
|