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:對流程任務進行管理,例如任務提醒、任務完成和創(chuàng)建任務等。
IdentityService:提供對流程角色數(shù)據(jù)進行管理的API,這些角色數(shù)據(jù)包括用戶組、用戶及它們之間的關系。
ManagementService:提供對流程引擎進行管理和維護的服務。
HistoryService:對流程的歷史數(shù)據(jù)進行操作,包括查詢、刪除這些歷史數(shù)據(jù)。
FormService:表單服務。
3.應用實例
3.1.開發(fā)組件
名稱 |
版本 |
HighGoDB |
安全版V4.5、企業(yè)版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="部門經(jīng)理審批" 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="總經(jīng)理審批" 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()); }
|
日志打印輸出

查看數(shù)據(jù)庫表act_ge_bytearray中會增加一條數(shù)據(jù),對應的就是剛剛新增的流程。

查看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("任務創(chuàng)建時間:"+task.getCreateTime()); } }
|

查詢的數(shù)據(jù)來自表act_ru_task,需要注意的是act_ru_task 表中的數(shù)據(jù)只有需要處理的任務,一但任務完成,則會刪除已完成任務的數(shù)據(jù)。

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的數(shù)據(jù)不再了,新增了李四的數(shù)據(jù)

3.8.完成任務
任務處理只需重復執(zhí)行上述方法即可,只是更改了任務的處理人,直至任務結束。
@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()); } }
|
