Camunda工作流引擎簡單入門
官網:https://camunda.com/
官方文檔:https://docs.camunda.org/get-started/spring-boot/project-setup/
閱讀新體驗:http://www.zhouhong.icu/post/155
一、簡介
Camunda是一個工作流引擎,執行Bpmn2.0标準,是以依賴于基于bpmn的流程圖(本質上是一個xml檔案)
二、一個完整的報帳 demo 入門
1、建立一個SpringBoot項目,導入資料庫依賴、Camunda 等依賴
1 <dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-web</artifactId>
4 </dependency>
5 <dependency>
6 <groupId>org.mybatis.spring.boot</groupId>
7 <artifactId>mybatis-spring-boot-starter</artifactId>
8 <version>2.2.0</version>
9 </dependency>
10
11 <!-- https://mvnrepository.com/artifact/org.camunda.bpm.springboot/camunda-bpm-spring-boot-starter-webapp -->
12 <dependency>
13 <groupId>org.camunda.bpm.springboot</groupId>
14 <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
15 <version>3.4.4</version>
16 </dependency>
17 <!-- https://mvnrepository.com/artifact/org.camunda.bpm.springboot/camunda-bpm-spring-boot-starter-rest -->
18 <dependency>
19 <groupId>org.camunda.bpm.springboot</groupId>
20 <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId>
21 <version>3.4.4</version>
22 </dependency>
23
24 <dependency>
25 <groupId>mysql</groupId>
26 <artifactId>mysql-connector-java</artifactId>
27 <scope>runtime</scope>
28 </dependency>
29 <dependency>
30 <groupId>org.projectlombok</groupId>
31 <artifactId>lombok</artifactId>
32 <optional>true</optional>
33 </dependency>
34 <dependency>
35 <groupId>org.springframework.boot</groupId>
36 <artifactId>spring-boot-starter-test</artifactId>
37 <scope>test</scope>
38 </dependency>
39 <dependency>
40 <groupId>junit</groupId>
41 <artifactId>junit</artifactId>
42 <version>4.13.2</version>
43 </dependency>
44 <dependency>
45 <groupId>com.aliyun</groupId>
46 <artifactId>aliyun-java-sdk-ecs</artifactId>
47 <version>4.17.6</version>
48 </dependency>
application.yml 部配置設定置:
1 spring:
2 application:
3 name: camunda-demo
4 #資料源配置
5 datasource:
6 url: jdbc:mysql://127.0.0.1:3306/camunda-demo?serverTimezone=Asia/Shanghai
7 driver-class-name: com.mysql.cj.jdbc.Driver
8 username: root
9 password: 123456
10 camunda:
11 bpm:
12 #配置賬戶密碼來通路Camunda自帶的管理界面
13 admin-user:
14 id: admin
15 password: admin
16 first-name: admin
17 filter:
18 create: All tasks
19 #禁止自動部署resources下面的bpmn檔案
20 auto-deployment-enabled: false
2、啟動後會生成47張表:
3、通路 http://localhost:8080/
4、下載下傳bpmn模組化工具:https://camunda.com/download/modeler/
5、畫一個報帳流程圖,申請人為shangsan、人事為lisi、經理為wangwu,儲存後放到項目resources目錄下面,同時進入控制台Admin目錄下建立相關的人員資訊。
注意:報帳金額判斷條件使用 Expression 表達式
6、流程定義部署
@PostMapping("/deploy")
public void deploy() {
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("BPMN/apply.bpmn")
.deploy();
System.out.println(deploy.getId());
}
用PostMan發起流程後會在ACT_RE_DEPLOYMENT表中看到一個流程的執行個體
7、啟動流程執行個體
@PostMapping("/start")
public void runProcinst(){
Map<String,Object> params = new HashMap<>();
params.put("money",2001);
ProcessInstance holiday = runtimeService.startProcessInstanceByKey("apply",params);
}
然後切換到zhangsan使用者,在控制台TaskList下檢視
8、審批通過,在審批的過程中可以随意添加審批資訊
@PostMapping("/taskComplete")
public void taskComplete(){
Task task = taskService.createTaskQuery()
.taskAssignee("zhangsan")
.singleResult();
params.put("approve2","lisi");
Map<String,Object> params = new HashMap<>();
taskService.complete(task.getId(),params);
}
切換 lisi 使用者在控制台檢視任務
9、進入控制台在Cockplt中檢視流程走到哪(因為我們的money設定的是2001,大于2000,是以流程走到下面的那個分支)
10、其他關于流程的一些簡單操作
1 /**
2 * @ClassName: camunda-demo
3 * @Description:
4 * @Author: zhouhong
5 * @Create: 2021-07-08 10:06
6 **/
7
8 @RestController
9 public class Test {
10
11 @Autowired
12 RepositoryService repositoryService;
13 @Autowired
14 RuntimeService runtimeService;
15 @Autowired
16 TaskService taskService;
17 @Autowired
18 HistoryService historyService;
19 @Autowired
20 ProcessEngine processEngine;
21
22 @Autowired
23 ProcessEngine engine;
24
25 /**
26 * @Description: 流程定義部署
27 * @Author: zhouhong
28 * @Date: 2021/7/8
29 */
30 @PostMapping("/deploy")
31 public void deploy() {
32 Deployment deploy = repositoryService.createDeployment()
33 .addClasspathResource("BPMN/apply.bpmn")
34 .deploy();
35 System.out.println(deploy.getId());
36 }
37
38 /**
39 * @Description: 開啟一個流程執行個體
40 * @Author: zhouhong
41 * @Date: 2021/7/8
42 */
43 @PostMapping("/start")
44 public void runProcinst(){
45 Map<String,Object> params = new HashMap<>();
46 params.put("money",2001);
47 ProcessInstance apply = runtimeService.startProcessInstanceByKey("apply",params);
48 System.out.println(apply.getProcessDefinitionId());
49 System.out.println(apply.getId());
50 System.out.println(apply.getProcessInstanceId());
51 }
52
53 /**
54 * @Description: 流程任務查詢
55 * @Author: zhouhong
56 * @Date: 2021/7/8
57 */
58 @PostMapping("/taskquery")
59 public void taskQuery() {
60 List<Task> tasks = taskService.createTaskQuery()
61 .processDefinitionKey("apply")
62 .list();
63 for (Task task : tasks) {
64 System.out.println(task.getAssignee());
65 System.out.println(task.getId());
66 System.out.println(task.getName());
67 System.out.println(task.getTenantId());
68 }
69 }
70
71 /**
72 * @Description: 目前需要處理的任務
73 * @Author: zhouhong
74 * @Date: 2021/7/8
75 */
76 @PostMapping("/mytaskquery")
77 public List<HistoricTaskInstance> myTaskQuery() {
78 List<HistoricTaskInstance> instances = engine.getHistoryService().createHistoricTaskInstanceQuery()
79 .taskAssignee("lisi").unfinished().orderByHistoricActivityInstanceStartTime().asc().list();
80 return instances;
81 }
82
83 /**
84 * @Description: 流程任務執行
85 * @Author: zhouhong
86 * @Date: 2021/7/8
87 */
88 @PostMapping("/taskComplete")
89 public void taskComplete(){
90 //目前lisi隻有一個任務,業務中根據場景選擇其他合适的方式
91 Task task = taskService.createTaskQuery()
92 .taskAssignee("zhangsan")
93 .singleResult();
94 Map<String,Object> params = new HashMap<>();
95 params.put("approve2","lisi");
96 taskService.complete(task.getId(),params);
97 }
98
99 /**
100 * @Description: 流程定義查詢
101 * @Author: zhouhong
102 * @Date: 2021/7/8
103 */
104 @PostMapping("/queryDefine")
105 public void queryDefine(){
106 ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
107 List<ProcessDefinition> definitions = query.processDefinitionKey("apply")
108 .orderByProcessDefinitionVersion()
109 .desc()
110 .list();
111 for (ProcessDefinition definition : definitions) {
112 System.out.println(definition.getDeploymentId());
113 System.out.println(definition.getName());
114 System.out.println(definition.getVersion());
115 System.out.println(definition.getId());
116 System.out.println(definition.getKey());
117 }
118 }
119
120 /**
121 * 删除流程定義
122 */
123 @PostMapping("/deleteDefine")
124 public void deleteDefine(){
125 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
126 List<ProcessDefinition> definitions = processDefinitionQuery.processDefinitionKey("apply")
127 .orderByProcessDefinitionVersion()
128 .asc()
129 .list();
130 ProcessDefinition processDefinition = definitions.get(0);
131 if (processDefinition != null){
132 repositoryService.deleteDeployment(processDefinition.getDeploymentId(),true);
133 }
134 }
135
136 /**
137 * 查詢曆史資訊
138 */
139 @PostMapping("/queryHistory")
140 public void queryHistory(){
141 List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
142 .finished()
143 .orderByHistoricActivityInstanceEndTime()
144 .asc()
145 .list();
146 for (HistoricActivityInstance instance : list) {
147 System.out.println(instance.getActivityId());
148 System.out.println(instance.getProcessDefinitionKey());
149 System.out.println(instance.getAssignee());
150 System.out.println(instance.getStartTime());
151 System.out.println(instance.getEndTime());
152 System.out.println("=============================");
153 }
154 }
155
156 /**
157 * 啟動一個流程執行個體,并且添加一個業務key
158 * 業務key 可以在 act_ru_execution 中看到
159 */
160
161 public void startProcInstAddBusinessKey(){
162 ProcessInstance apply = runtimeService.startProcessInstanceByKey("apply", "aaaa-scsc-89uc");
163 System.out.println(apply.getBusinessKey());
164 }
165
166 }
167